继续畅通工程
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 17840 Accepted Submission(s): 7682
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!!
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int per[110]; 6 struct node 7 { 8 int b,e,v; 9 }s[5050]; 10 bool cmp(node x,node y) 11 { 12 return x.v<y.v; 13 } 14 void init() 15 { 16 for(int i=0;i<110;i++) 17 per[i]=i; 18 } 19 int find(int x) 20 { 21 while(x!=per[x]) 22 x=per[x]; 23 return x; 24 } 25 bool join (int x,int y) 26 { 27 int fx=find(x); 28 int fy=find(y); 29 if(fx!=fy) 30 { 31 per[fx]=fy; 32 return true; 33 } 34 return false; 35 } 36 37 38 int main() 39 { 40 int n,i,flag; 41 while(scanf("%d",&n),n) 42 { 43 init(); 44 int m=n*(n-1)/2; 45 for(i=0;i<m;i++) 46 { 47 scanf("%d%d%d%d",&s[i].b,&s[i].e,&s[i].v,&flag); 48 if(flag)//最主要的就是把修过的路的价值清0 49 s[i].v=0; 50 } 51 sort(s,s+m,cmp); 52 int sum=0; 53 for(i=0;i<m;i++) 54 { 55 if(join(s[i].b,s[i].e)) 56 sum+=s[i].v; 57 } 58 printf("%d\n",sum); 59 } 60 return 0; 61 }