HDU 5253:连接的管道

来源:互联网 发布:软件测试工程师题库 编辑:程序博客网 时间:2024/05/23 23:42

最小生成树模板题


AC代码:

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int maxn = 2*1e6;int Map[1000][1000];int father[100005];int N,M,cnt;int dir[2][2] = {{1,0},{0,1}}; //向下,向右struct Edge{    int u;    int v;    int w;}edge[maxn];void buildGraph(){    int u,v,x,y;    for(int i = 0; i < N; i++)    {        for(int j = 0; j < M; j++)        {            u = i*M+j;            for(int k = 0; k < 2; k++)            {                x = i + dir[k][0];                y = j + dir[k][1];                if(x>=0&&x<N&&y>=0&&y<M)                {                    v = x*M+y;                    edge[cnt].u = u;                    edge[cnt].v = v;                    edge[cnt].w = abs(Map[i][j]-Map[x][y]);                    cnt++;                }            }        }    }}bool cmp(Edge a,Edge b){    return a.w < b.w;}void initSet(){    for(int i = 0; i < M*N; i++)        father[i] = i;}int findSet(int x){    int temp = x;    while(x != father[x])    {        x = father[x];    }    while(temp != father[temp])    {        temp = father[temp];        father[temp] = x;    }    return x;}void unionSet(int u,int v){    father[u] = v;}void kruskal(){    initSet();    int mst = 0;    int i = 0;    int num = 0;    while(i < cnt)    {        int u = edge[i].u;        int v = edge[i].v;        int fu = findSet(u);        int fv = findSet(v);        if(fu != fv)        {            unionSet(fu,fv);            mst += edge[i].w;            num++;            if(num == M*N-1)                break;        }        i++;    }    printf("%d\n",mst);}int main(){    int T,Case = 0;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&N,&M);        for(int i = 0; i < N; i++)            for(int j = 0; j < M; j++)                scanf("%d",&Map[i][j]);        cnt = 0;        buildGraph();        sort(edge,edge+cnt,cmp);        printf("Case #%d:\n",++Case);        kruskal();    }    return 0;}