HDU - 1863 畅通工程
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
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 ?
就是最小生成树,我直接用kruskal算法做的,里面附带解释
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 const int maxn = 1e3; 5 int p[maxn]; 6 int n,m; 7 struct face//存储数据 8 { 9 int u,v,w; 10 } edge[maxn*maxn]; 11 bool cmp(face a,face b)//权值排序 12 { 13 return a.w<b.w; 14 } 15 void init()//并查集1 16 { 17 for(int i=1; i<=n; i++) 18 p[i]=i; 19 } 20 int find(int x)//并查集2 21 { 22 return x==p[x]?x:p[x] = find(p[x]); 23 } 24 int kruskal()//核心算法 25 { 26 int ans=0; 27 init(); 28 sort(edge,edge+m,cmp);//此处就是将给的权值先排序 29 for(int i=0; i<m; i++) 30 { 31 int x = find(edge[i].u); 32 int y = find(edge[i].v); 33 if(x!=y) 34 { 35 ans+=edge[i].w; 36 p[x] = y; 37 } 38 } 39 return ans; 40 } 41 int main() 42 { 43 while(cin>>m>>n&&m)//但是注意输入,HDU - 1233 和HDU - 1863给的n和m不一样(切记注意) 44 { 45 for(int i=0; i<m; i++) 46 cin>>edge[i].u>>edge[i].v>>edge[i].w; 47 int sum=0,num=1; 48 int kk=kruskal(); 49 for(int i=1; i<=n; i++)//这个就是判断根个数!!! 50 { 51 if(p[i]==i) 52 { 53 sum++; 54 } 55 if(sum>1) //如果不加这个循环就可以做“还是畅通工程”,加上这句就是“畅通工程”,都是杭电题。 56 { 57 num=0; 58 break; 59 } 60 } 61 if(num) 62 cout<<kk<<endl; 63 else 64 cout<<'?'<<endl; 65 } 66 }