码迷,mamicode.com
首页 > 其他好文 > 详细

HDU - 1233 还是畅通工程(带权并查集和最小生成树)

时间:2017-03-27 22:23:53      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:准则   畅通工程   cst   min   hdu   产生   div   没有   clu   

题意:用路把各个村庄连起来,不一定要有直接的公路相连,只要能间接通过公路可达即可,给出每两个村庄之间的距离,求畅通需要的最少长度。

1.最小生成树 Kruskal 解法

先按长度从小到大排序,因为要求最短,那肯定要先把短的连起来,如果有一条边还没有连起来,并且这条边上的两个点在两个连通分量中,那就连接起来。

可以用第二组数据模拟一遍(排序后):

4

1 2 1

1 4 1

2 4 2

2 3 3

1 3 4

3 4 5

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int maxn=111;
 6 int Father[maxn];
 7 
 8 struct stt{
 9     int c1;
10     int c2;
11     int dis;
12 }T[5000];
13 
14 bool cmp(stt a,stt b){
15     return a.dis<b.dis;    
16 }
17 
18 int find(int x){return x==Father[x]?x:Father[x]=find(Father[x]);}
19 
20 void Union(int x,int y){
21     int fx=find(x),fy=find(y);
22     if(fx!=fy){
23         Father[fx]=fy;
24     }
25 }
26 
27 int main(){
28     int n;
29     while(scanf("%d",&n)!=EOF&&n!=0){
30         
31         for(int i=1;i<=n;i++){
32             Father[i]=i;
33         }
34         
35         int len=n*(n-1)/2;
36         
37         for(int i=1;i<=len;i++){
38             scanf("%d %d %d",&T[i].c1,&T[i].c2,&T[i].dis);
39         }
40         
41         sort(T+1,T+len+1,cmp);//长度短的优先连接 
42         int minlen=0;
43         
44         for(int i=1;i<=len;i++){
45             if(find(T[i].c1)!=find(T[i].c2)){//如果要连的那条边上的两个点在两个连通分量中,就把他们连接起来咯 
46                 minlen+=T[i].dis;
47                 Union(T[i].c1,T[i].c2);
48             }
49         }
50         
51         printf("%d\n",minlen);
52     }
53     return 0;    
54 }

其实就是并查集问题,只不过用到最小生成树的思想。

思想步骤:

每一个步骤选择一条边加入生成树
贪心准则:不会产生环路,且耗费最小
可按照耗费递增顺序考察每条边:
(1)若产生环路,丢弃
(2)否则加入 

 

HDU - 1233 还是畅通工程(带权并查集和最小生成树)

标签:准则   畅通工程   cst   min   hdu   产生   div   没有   clu   

原文地址:http://www.cnblogs.com/Leonard-/p/6628418.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!