最小生成树 Kruskal(克鲁斯卡尔)算法

Description

省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。 

 

Input

测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N 
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。 

 

Output

对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。 

 

Sample Input

 

3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100

 

Sample Output

 

3 ?

 

AC代码:

#include #include #include #include #include using namespace std; const int N=10000+20; int uset[N]; int ran[N]; struct Node {     int x,y,price; } s[N]; bool cmp(Node a,Node b) //按权值从小到大排序 {     return a.priceran[b])         uset[b]=a;     else     {         if(ran[a]==ran[b])             ran[b]++;         uset[a]=b;     } } int kruskal(int n,int m) //克鲁斯卡尔算法 {     int res=0,i;     sort(s+1,s+n+1,cmp);     for(i=1; i<=n; i++)     {         if(find(s[i].x)!=find(s[i].y))         {             unionset(s[i].x,s[i].y);             res +=s[i].price;         }     }     return res; } int main() {     int n,m;     int i,j;     int ans=0;     while(scanf("%d%d",&n,&m)!=EOF&&n)     {         ans=0;         makeset(m);         for(i=1; i<=n; i++)             scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].price);         ans=kruskal(n,m);         for(i=2; i<=m; i++) //判断所有城市有没有连到一起 及测试连通性         {             if(find(1)!=find(i))             {                 ans=-1;                 break;             }         }         if(ans==-1)             printf("?\n");         else             printf("%d\n",ans);     }     return 0; }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(acm算法)