继续畅通工程
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10914 Accepted Submission(s): 4763
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;
数据结构:由于数据量小,可以用临接矩阵直接存储图
AC代码:
1 #include<stdio.h> 2 #include<string.h> 3 int vis[101]; 4 int price[101]; 5 int map[101][101]; 6 void init(int n) 7 { 8 int i; 9 memset(vis,0,sizeof(vis)); 10 for(i = 1;i <= n;i ++) 11 price[i] = map[1][i]; 12 } 13 14 int main() 15 { 16 int i,j,k,n; 17 int min,a,b,c,d,sum; 18 while(~scanf("%d",&n) && n) 19 { 20 sum = 0; 21 for(i = 0;i < (n*(n-1))/2;i ++) 22 { 23 scanf("%d%d%d%d",&a,&b,&c,&d); 24 map[b][a] = map[a][b] = c; 25 if(d) 26 map[b][a] = map[a][b] = 0; 27 } 28 init(n); 29 vis[1] = 1; 30 for(i = 0;i < n;i ++) 31 { 32 k = 0; 33 min = 1 << 30; 34 for(j = 1;j <= n;j ++) 35 { 36 if(!vis[j] && min > price[j]) 37 { 38 min = price[j]; 39 k = j; 40 } 41 } 42 if(min != 1 << 30) 43 sum += min; 44 vis[k] = 1; 45 for(j = 1;j <= n;j ++) 46 { 47 if(!vis[j] && price[j] > map[k][j]) 48 price[j] = map[k][j]; 49 } 50 } 51 printf("%d ",sum); 52 } 53 return 0; 54 }