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
3 5 <div style='font-family:Times New Roman;font-size:14px;background-color:F4FBFF;border:#B7CBFF 1px dashed;padding:6px'><div style='font-family:Arial;font-weight:bold;color:#7CA9ED;border-bottom:#B7CBFF 1px dashed'><i>Hint</i></div>Hint</div> Huge input, scanf is recommended.(1):大意:某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。(2): 思路先用快速排序将所有路径按照从小到大的顺序排列,然后用一个节点标记数组,初值为1,将排在第一个的路径的前一个节点的标记设为0。之后进行计算,凡是前后路径标记之和为1的,说明之前两条路是不连通的,将长度加上,如果两条路之和加上为2,说明这两个节点之前已经可以走通了。每次搜索出来一个节点长度,就要返回从第一个重新开始搜索,以免少计算路径。直到所有路径全部搜索完毕,结束。求出的路径之和即为所求的最短路径即最小生成树。
(3)感想:
最小生成树问题,了解题意,明白方法以及如何使用,再加上仔细认真就好。
#include <stdio.h> #include <string.h> #include <algorithm> const int N = 101; int map[N][N]; int mark[N]; int i,j,n; int prim() { int sum = 0; int min,t = n,k; while(--t) { min = 100000; for (i = 2; i <= n; i++) { if(mark[i] != 1 && min > map[1][i]) { min = map[1][i]; k = i; } } sum += min; mark[k] = 1; for (i = 2; i <= n; i++) { if(mark[i] != 1 && map[k][i] < map[1][i]) map[1][i] = map[k][i]; } } return sum; } int main() { int x,y,len,num; while(scanf("%d",&n) && n != 0) { num = n*(n-1)/2; memset(map,0,sizeof(map)); for (i = 1; i <= num; i++) { scanf("%d%d%d",&x,&y,&len); map[x][y] = map[y][x] = len; } memset(mark,0,sizeof(mark));
printf("%d\n",prim()); } return 0; }