ACM 继续畅通工程

Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
 

 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。

当N为0时输入结束。
 

 

Output
每个测试用例的输出占一行,输出全省畅通需要的最低成本。
 

 

Sample Input
3 1 2 1 0 1 3 2 0 2 3 4 0 3 1 2 1 0 1 3 2 0 2 3 4 1 3 1 2 1 0 1 3 2 1 2 3 4 1 0
 

 

Sample Output
3 1 0
 

 

Author
ZJU
 

 

Source
 
 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 struct node
 6 {
 7     int a,b,v;
 8 }loab[5055];
 9 
10 int parent[105];
11 
12 void init()
13 {
14     for(int i = 0; i < 105; i++)
15         parent[i] = i;
16 }    
17 
18 int find(int n)
19 {
20     if(parent[n] == n)
21         return n;
22     else
23         return find(parent[n]);
24 }
25 
26 bool merge(int a,int b)      
27 {
28     a = find(a);
29     b = find(b);
30     if(a != b)
31     {
32         parent[b] = a;
33         return true;
34     }else{
35         return false;
36     }
37 }
38 
39 bool cmp(node a,node b)      //sort函数定义 
40 {
41     return a.v < b.v;
42 }
43 int main()
44 {
45     int n,flag,t;
46     /*
47         ~scanf("%d",&n)&&n
48     */
49     while(cin>>n&&n)
50     {
51         
52         init();                                                //parent数组初始化 
53         t = n*(n-1)/2;
54         for(int i = 0; i < t; i++)
55         {
56             //cin>>loab[i].a>>loab[i].b>>loab[i].v>>flag;      //使用cin输入时 会TLE  
57                 scanf("%d%d%d%d",&loab[i].a,&loab[i].b,&loab[i].v,&flag);
58             if(flag)                                        //当道路已经建成时把值重设为0,这样把问题给简单化 
59                 loab[i].v = 0;
60         }
61         sort(loab,loab+t,cmp);
62         int sum = 0;
63         for(int i = 0; i < t; i++)
64         {
65             bool temp = merge(loab[i].a,loab[i].b);         //构建最小生成树 
66             if(temp)                                       //只取道路成本较小的 
67                 sum += loab[i].v;
68         }
69         cout << sum <<endl;
70     }
71      return 0;
72 }

 

posted @ 2017-08-08 10:34  听说这是最长的名字了  阅读(204)  评论(0编辑  收藏  举报