还是畅通工程
还是畅通工程
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
Sample Output
3
5
1 #include <stdio.h> 2 #include <string.h> 3 4 #define INF 200000000 5 #define MAX 105 6 7 int Prim(int n, int map[][MAX]) 8 { //最小生成树算法 9 10 //存放集合s中顶点以外的顶点到s的最短距离 11 int lowCost[MAX]; 12 //存放集合s中顶点以外的顶点到s的最短距离的顶点 13 int closest[MAX]; 14 int s[MAX]; //存放已生成的顶点 15 int min; 16 int u; 17 int dist = 0; //最小生成树的总长度 18 int i, j; 19 //初始化数组 20 memset(s,0,sizeof(s)); 21 memset(lowCost, 0, sizeof(lowCost)); 22 memset(closest, 0, sizeof(closest)); 23 for (i=1; i<=n; i++) 24 { //以1为起点建立最小生成树 25 lowCost[i] = map[1][i]; 26 closest[i] = 1; 27 } 28 s[1] = 1; //将起点1放入集合s 29 for (j=1; j<=n-1; j++) 30 { //进行n-1次循环 31 min = INF; 32 u = 1; 33 //找到距i最近的顶点 34 for (i=1; i<=n; i++) 35 if (lowCost[i]<min&&!s[i]) 36 { 37 min = lowCost[i]; 38 u = i; 39 } 40 s[u] = 1; 41 dist += lowCost[u]; 42 //用顶点u跟新lowCost和closest 43 for (i=1; i<=n; i++) 44 if (map[u][i]<lowCost[i]&&!s[i]) 45 { 46 lowCost[i] = map[u][i]; 47 closest[i] = u; 48 } 49 } 50 return dist; 51 } 52 53 int main() 54 { 55 int n; 56 int map[MAX][MAX]; //邻接矩阵 57 int a,b,c; 58 int dist; 59 int i; 60 while (~scanf("%d",&n)) 61 { 62 if (n==0) 63 break; 64 for (i=1; i<=n*(n-1)/2; i++) 65 { 66 scanf("%d%d%d",&a,&b,&c); 67 map[a][b] = map[b][a] = c; 68 } 69 dist = Prim(n,map); 70 printf("%d\n",dist); 71 } 72 return 0; 73 }
蒹葭苍苍,白露为霜;
所谓伊人,在水一方。