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 }
View Code
posted @ 2018-09-01 19:31  Free-Fly  阅读(154)  评论(0编辑  收藏  举报