【HDU】5253-连接的管道(并查集)

来源:互联网 发布:98印尼排华知乎 编辑:程序博客网 时间:2024/05/18 21:07

十分简单的并查集问题,注意建图的方式

#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1005;const int maxd = 5000005;const int dir[2][2] = {{0,1},{1,0}};int n,m,mat[maxn][maxn],cnt,fa[maxd];struct Node{    int u,v,d;    friend bool operator < (Node p,Node q){        return p.d < q.d;    }}edge[maxd];void init(){    for(int x = 0; x < n; x++)        for(int y = 0; y < m; y++){            for(int d = 0; d < 2; d ++){                int xx = x + dir[d][0];                int yy = y + dir[d][1];                if(xx >= 0 && xx < n && yy >= 0 && yy < m){                    edge[cnt].u = x * m + y;                    edge[cnt].v = xx * m + yy;                    edge[cnt].d = abs(mat[xx][yy] - mat[x][y]);                    cnt ++;                }            }        }}int find_father(int u){    return fa[u] == u ? u : fa[u] = find_father(fa[u]);}int main(){    int T,Case = 1;    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);        cnt = 0;        int t = n * m;        for(int i = 0; i <= t; i ++) fa[i] = i;        for(int i = 0; i < n; i++)            for(int j = 0; j < m; j++)                scanf("%d",&mat[i][j]);        init();        sort(edge,edge + cnt);        int ans = 0;        printf("Case #%d:\n",Case++);        for(int i = 0; i < cnt; i++){            int f1 = find_father(edge[i].u);            int f2 = find_father(edge[i].v);            if(f1 != f2){                //printf("%d %d %d\n",edge[i].u,edge[i].v,edge[i].d);                ans += edge[i].d;                fa[f1] = f2;            }        }        printf("%d\n",ans);    }    return 0;}

1 0