杭电ACM专题四1004

来源:互联网 发布:加油站收入 知乎 编辑:程序博客网 时间:2024/06/11 14:56

Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。<br>
 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。<br>当N为0时,输入结束,该用例不被处理。<br>
 

Output
对每个测试用例,在1行里输出最小的公路总长度。<br>
 

Sample Input
31 2 11 3 22 3 441 2 11 3 41 4 12 3 32 4 23 4 50
 

Sample Output
35<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; }

0 0