码迷,mamicode.com
首页 > 其他好文 > 详细

UVALive-7303- Aquarium【最小生成树】【连通块】

时间:2016-08-09 23:26:44      阅读:455      评论:0      收藏:0      [点我收藏+]

标签:


UVALive - 7303- Aquarium


技术分享
技术分享

题目链接:7303

题目大意:给你一个r * c的格子,每个格子有一个 ‘ \ ’ 或者 ‘/’ 的墙,以及打掉墙的费用,问使得所有块联通的最小费用。(看图好理解)

题目思路:就是将他化成一个图,联通的块相当于一个点,两个点之间有一条边,边的权值为墙的费用。

转化为连通块的思路是:每个格子看成两部分,左侧和右侧。以一行来看,假设两个格子A,B。那么B格子的右侧的编号一定和A格子的左侧的编号相同。如图所示
技术分享
给每个格子的左右侧标上号,然后加入边,边的两个端点为一个格子的两个编号。权值为墙的费用

然后处理行与行之间的边,稍微讨论一下,假设上边格子为A,下面格子为B。那么如果A是‘/’,B是’/’,那么A的右格子和B的左格子是相通的,这时候加一条边,将权值设为0就可以了。

注意数组大小!!!

以下是代码:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <functional>
#include <numeric>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#include <deque>
#include <list>
using namespace std;

typedef long long ll;
string s[105];
int val[105][105];
struct node
{
    int a,b;
}g[105][105];
struct node2
{
    int a,b,len;
}edge[40005];
int fa[20005];
int kk;
//=======最小生成树====
void add(int u, int v,int w)
{
    edge[kk].a = u;
    edge[kk].b = v;
    edge[kk++].len = w;
}
bool cmp(node2 a,node2 b)
{
    return a.len < b.len;
}
int getfather(int v)
{
    return (fa[v] == v) ? v : fa[v] = getfather(fa[v]);
}
void merges(int x,int y)
{
    x = getfather(x);
    y = getfather(y);
    if (x != y) fa[x] = y;
}
//==============
int main()
{
    int t;
    cin >> t;
    int lllll = 1;
    while(t--)
    {
        int c,r;
        cin >> c >> r;
        kk = 0;
        for (int i = 0; i < c; i++)
        {
            cin >> s[i];
        }
        for (int i = 0; i < c; i++)
        {
            for (int j = 0; j < r; j++)
            {
                cin >> val[i][j];
            }
        }
        int p = 1;
        for (int i = 0; i < c; i++)
        {
            for (int j = 0; j < r; j++)
            {
                if (j == 0)
                {
                    g[i][j].a = p++;
                    g[i][j].b = p++;
                    add(g[i][j].a,g[i][j].b,val[i][j]);
                }
                else
                {
                    g[i][j].a = g[i][j - 1].b;
                    g[i][j].b = p++;
                    add(g[i][j].a,g[i][j].b,val[i][j]);
                }
                if (i != 0)
                {
                    if (s[i - 1][j] == ‘/‘)
                    {
                        if (s[i][j] == ‘/‘)
                        {
                            add(g[i][j].a,g[i - 1][j].b,0);
                        }
                        else
                        {
                            add(g[i][j].b,g[i - 1][j].b,0);
                        }
                    }
                    else
                    {
                        if (s[i][j] == ‘/‘)
                        {
                            add(g[i][j].a,g[i - 1][j].a,0);
                        }
                        else
                        {
                            add(g[i][j].b,g[i - 1][j].a,0);
                        }
                    }
                }
            }
        }
        for (int i = 1; i <= 20001; i++)
        {
            fa[i] = i;
        }
        sort(edge,edge + kk,cmp);
        int ans = 0;
        for (int i = 0; i < kk; i++)
        {
            int u = edge[i].a;
            int v = edge[i].b;
            if (getfather(u) != getfather(v))
            {
                merges(u,v);
                ans += edge[i].len;
            }
        }
        printf("Case %d: ",lllll++);
        cout << ans << endl;
    }
}

UVALive-7303- Aquarium【最小生成树】【连通块】

标签:

原文地址:http://blog.csdn.net/loy_184548/article/details/52166856

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!