HDU 1233 还是畅通工程(最小生成树)krusal算法

开了最小生成树的专题,感觉和并查集很相似(krusal算法),
但prim算法就…过几天再用prim算法写下这个题

这道题中,按村庄间的距离从小到大排序,保证村庄之间的距离都是剩下村庄之间最小的
用 sum表示公路的长度,用int数组pre[ ] 来记录村庄是否连通
(判断根节点是否相同)
如果相同,表示联通,继续查找;如果不同,表示还未联通,sum=sum+距离,unit()合并入根节点

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string.h>
using namespace std;

int pre[10000]; // 

struct node
{
    int a,b,w;  //结构体 储存村庄标号  以及村庄间的距离

}i[11000];

bool cmp(node xx,node yy)   //村庄间的距离从小到大排序
{
    if(xx.w!=yy.w)
        return xx.w<yy.w;
}

int find(int x)   //并查集中的查找根节点
{
    while(x!=pre[x])
     x=pre[x];

   return x;
}

 void unit(int tx,int ty)   //并查集中的根节点的合并
 {
     int fx=find(tx);
     int fy=find(ty);

     if(fx!=fy)
      pre[fy]=fx;

 }

 int main()
 {
     int c,d,n,m;
     while(cin>>n)
     {
         if(n==0)
            break;

         for(c=1;c<=n;c++)  //初始化
            pre[c]=c;

         int N=n*(n-1)/2;

         for(c=1;c<=N;c++)    //输入村庄的标号  距离
             cin>>i[c].a>>i[c].b>>i[c].w;

          sort(i+1,i+N+1,cmp);  //排序

          int sum=0;
            for(c=1;c<=N;c++)         //挨个查找
            {
                int fa=find(i[c].a);
                int fb=find(i[c].b);


                if(fa!=fb)            //如果根节点不同,说明还未联通 
                {                           
                    sum=sum+i[c].w;    //修这两个村庄之间的道路,sum=sum+距离
                    unit(fa,fb);       //村庄并入根节点,表示已修通道路
                }

            }
            cout<<sum<<endl;

     }

     return 0;

 }

点赞