题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1879
继续畅通工程
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 14075 Accepted Submission(s):
6136
Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的
N(N-1)/2
行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。
当N为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
题目大意:这道题目也没有什么特别的,记得排序,这是一个最小生成树问题。多了一个路是否已经存在。如果存在就不用在建路了,这样的花费为0。if(p[i].g==1)p[i].f=0;这就可以了。
附上代码。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 struct node 6 { 7 int s,d,f,g; 8 } p[5000]; 9 10 int father[110],sum,k; 11 12 void set(int n) 13 { 14 for (int i=1; i<=n; i++) 15 father[i]=i; 16 } 17 18 bool cmp(const node &a,const node &b) 19 { 20 return a.f<b.f; 21 } 22 23 int find(int a) 24 { 25 if (father[a]==a)return a; 26 return father[a]=find(father[a]); 27 } 28 29 void Union(int x,int y,int z) 30 { 31 x=find(x); 32 y=find(y); 33 if (x!=y) 34 { 35 sum+=z; 36 father[x]=y; 37 k++; 38 } 39 } 40 41 int main () 42 { 43 int n; 44 while (scanf("%d",&n),n) 45 { 46 sum=0;k=0; 47 set(n); 48 for (int i=1; i<=n*(n-1)/2 ; i++) 49 { 50 scanf("%d%d%d%d",&p[i].s,&p[i].d,&p[i].f,&p[i].g); 51 if(p[i].g==1) 52 p[i].f=0; 53 } 54 sort(p+1,p+n*(n-1)/2+1,cmp); 55 for (int i=1; i<=n*(n-1)/2; i++) 56 { 57 Union(p[i].s,p[i].d,p[i].f); 58 if(k==n) 59 break; 60 } 61 printf ("%d ",sum); 62 } 63 return 0; 64 }