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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 1233 还是畅通工程(带权并查集和最小生成树)相关的知识,希望对你有一定的参考价值。

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

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 还是畅通工程(带权并查集和最小生成树)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1233 还是畅通工程(最小生成树, Prim+优先队列 || Kruskal+并查集)

HDU 1233 还是畅通工程

hdu2818(带权并查集)

HDU 3047 Zjnu Stadium 带权并查集

Travel(HDU 5441 2015长春区域赛 带权并查集)

HDU1289 A Bug's Life (带权并查集)