Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2793204
  • 博文数量: 471
  • 博客积分: 7081
  • 博客等级: 少将
  • 技术积分: 5369
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-04 21:55
文章分类

全部博文(471)

文章存档

2014年(90)

2013年(69)

2012年(312)

分类: C/C++

2012-05-08 16:05:20


Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
 

Output
对每个测试用例,在1行里输出最小的公路总长度。
 

Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
 

Sample Output
3
5



点击(此处)折叠或打开

  1. /*
  2.  * Introduction to Algorithms
  3.  * Chapter 23 --- MST.Kruskal
  4.  */
  5.  
  6. #include <iostream>
  7. #include <algorithm>
  8. using namespace std;
  9.  
  10. const int maxint = 999999;
  11.  
  12. typedef struct Road{
  13.     int c1, c2; // a到b
  14.     int value; // 权值
  15. }Road;
  16.  


  17. Road road[50005];//(N<100hdu输入数据超出100) 设一个比较大的值,实际看输入最小生成树中:边数e=n-1
  18. int node[50006];//最小生成树:n顶点数
  19.  
  20. bool myCmp(const Road &a, const Road &b)
  21. {
  22.     if(a.value < b.value)
  23.         return 1;
  24.     return 0;
  25. }
  26.  
  27. //node[2]=1 node[8]=1 ,node[3]=1,共同的祖先,如果(3,8)加进去,则构成回路,不要
  28. //有点像并查集
  29. int Find_Set(int n)
  30. {
  31.     if(node[n] == -1)
  32.         return n;
  33.     return node[n] = Find_Set(node[n]);
  34. }
  35.  
  36. bool Merge(int s1, int s2)
  37. {
  38.     int r1 = Find_Set(s1);
  39.     int r2 = Find_Set(s2);
  40.     if(r1 == r2)//如果相等证明构成回路,则直接返回一个0,不要把顶点加进来(下一步是加进去的)
  41.         return 0;
  42.     if(r1 < r2)
  43.         node[r2] = r1;
  44.     else
  45.         node[r1] = r2;
  46.     return 1;
  47. }
  48.  
  49. int main()
  50. {
  51.    
  52.     int no;//实际的点
  53.     while(scanf("%d",&no)!=EOF && no)
  54.     {
  55.         //初始化全为-1
  56.         memset(node, -1, sizeof(node));
  57.         int line;//记录实际关系数
  58.         line=no*(no-1)/2;
  59.         int i;
  60.         for(i=0; i<line; ++i)
  61.         {
  62.             scanf("%d%d%d",&road[i].c1,&road[i].c2,&road[i].value);
  63.         }
  64.         sort(road, road+line, myCmp);//按权值升序排序
  65.         int sum = 0, count = 0; // sum是MST的值,count是记录已使用的点数
  66.         for(i=0; i<line; ++i)
  67.         {
  68.             if(Merge(road[i].c1, road[i].c2))//如果返回的为0,则证明构成回路,不要加进
  69.              {
  70.                 count ++;
  71.                 sum += road[i].value;
  72.             }
  73.             if(count == no-1)//e=n-1已经连通,可以退出
  74.                 break;
  75.         }
  76.         cout << sum << endl;
  77.     }
  78.     return 0;
  79. }


阅读(804) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~