关闭

hdu 5253 连接的管道(最小生成树)

96人阅读 评论(0) 收藏 举报
分类:

连接的管道

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2445    Accepted Submission(s): 886


Problem Description
老 Jack 有一片农田,以往几年都是靠天吃饭的。但是今年老天格外的不开眼,大旱。所以老 Jack 决定用管道将他的所有相邻的农田全部都串联起来,这样他就可以从远处引水过来进行灌溉了。当老 Jack 买完所有铺设在每块农田内部的管道的时候,老 Jack 遇到了新的难题,因为每一块农田的地势高度都不同,所以要想将两块农田的管道链接,老 Jack 就需要额外再购进跟这两块农田高度差相等长度的管道。

现在给出老 Jack农田的数据,你需要告诉老 Jack 在保证所有农田全部可连通灌溉的情况下,最少还需要再购进多长的管道。另外,每块农田都是方形等大的,一块农田只能跟它上下左右四块相邻的农田相连通。
 

Input
第一行输入一个数字T(T10),代表输入的样例组数

输入包含若干组测试数据,处理到文件结束。每组测试数据占若干行,第一行两个正整数 N,M(1N,M1000),代表老 Jack 有N行*M列个农田。接下来 N 行,每行 M 个数字,代表每块农田的高度,农田的高度不会超过100。数字之间用空格分隔。
 

Output
对于每组测试数据输出两行:

第一行输出:"Case #i:"。i代表第i组测试数据。

第二行输出 1 个正整数,代表老 Jack 额外最少购进管道的长度。
 

Sample Input
2 4 3 9 12 4 7 8 56 32 32 43 21 12 12 2 3 34 56 56 12 23 4
 

Sample Output
Case #1: 82 Case #2: 74
思路:以相邻两块田作为起点和终点,以他们的高度差为边权建最小生成树
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1005;
int map[maxn][maxn];
int pre[maxn * maxn];
struct Node{
   int from,to,val;
}node[maxn * maxn * 2];
bool cmp(Node a,Node b)
{
    return a.val < b.val;
}
int find(int x)
{
    if(pre[x] != x)
        pre[x] = find(pre[x]);
    return pre[x];
}
int main()
{
    int t,n,m,kcase = 1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        int k = 0;
        memset(map,0,sizeof(map));
        for(int i =  1 ; i <= n * m ; i++)
            pre[i] = i;
        for(int i = 1 ; i <= n ; i++)
            for(int j = 1 ; j <= m ; j++)
                scanf("%d",&map[i][j]);
        for(int i = 1; i <= n ; i++)
            for(int j = 1 ; j <= m ; j++)
            {
                if(j+1 <= m)
                {
                    node[k].from = (i - 1) * m + j;
                    node[k].to = (i - 1) * m + j + 1;
                    node[k].val = abs(map[i][j] - map[i][j+1]);
                    k++;
                }
                if(i+1 <= n)
                {
                    node[k].from = (i - 1) * m + j;
                    node[k].to = i * m + j;
                    node[k].val = abs(map[i][j] - map[i+1][j]);
                    k++;
                }
            }
            int f = k;long long sum = 0;
            sort(node,node+f,cmp);
            for(int i = 0 ; i < f ; i++)
            {
                  int fx = find(node[i].from);
                  int fy = find(node[i].to);
                  if(fx != fy){
                       pre[fx] = fy;
                       sum += node[i].val;
                  }
            }
            printf("Case #%d:\n",kcase++);
            printf("%lld\n",sum);
    }
    return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:19712次
    • 积分:2159
    • 等级:
    • 排名:第18180名
    • 原创:209篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条