HDU 1233 还是畅通工程

Portal: http://acm.hdu.edu.cn/showproblem.php?pid=1233

最小生成树模板题

kruskal+并查集

因为给出了所有村庄间的距离,所以保证所有村庄在一个强连通分量里,所以直接kruskal

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<set>
 4 #include<cstdio>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<vector>
 8 using namespace std;
 9 #define FOR(i,j,k) for(int i=j;i<=k;i++)
10 #define FORD(i,j,k) for(int i=j;i>=k;i--)
11 #define LL long long
12 #define maxnn 10110
13 #define maxn 110
14 struct edge{int u,v,cost;};
15 edge bb[maxnn];
16 int father[maxn],val[maxn];
17 int n,x,y,z,k,ans;
18 void setinit()
19 {
20     FOR(i,1,n)
21     {father[i]=i; val[i]=1;}
22 }
23 int setfind(int x)
24 {
25     int fa=father[x];
26     if(fa==x) return x;
27     else return father[x]=setfind(fa);
28 }
29 bool setunion(int xx,int yy)
30 {
31     int XX=setfind(xx);
32     int YY=setfind(yy);
33     if(XX==YY) return false;
34     if(val[XX]>val[YY]) father[YY]=XX;
35     else father[XX]=YY;
36     if(val[XX]=val[YY]) val[XX]++;
37     return true;
38 }
39 bool cmp1(edge a,edge b)
40 {
41     return a.cost<b.cost;
42 }
43 void kruskal()
44 {
45     sort(bb+1,bb+k+1,cmp1);
46     FOR(i,1,k)
47     if(setunion(bb[i].u,bb[i].v)) ans+=bb[i].cost;
48 }
49 int main()
50 {
51 for(cin>>n;n!=0;cin>>n)
52 {
53     k=n*(n-1)/2;
54     FOR(i,1,n*(n-1)/2)    
55     {
56         cin>>x>>y>>z;
57         bb[i].u=x;
58         bb[i].v=y;
59         bb[i].cost=z;
60     }
61     setinit();
62     ans=0;
63     kruskal();
64     cout<<ans<<endl;
65 }
66 return 0;
67 }
路建多了也不好

也可以用Prim,改天写一个