个人心得:就是最小生成树的运用,还是要理解好每次都是从已搭建好的生成树里面选择与她的补集中最短距离,所以那个book数组的更新
需要好生体会。不过还是有缺陷,算法的复杂度为O(n^2),看介绍说用优先队列加堆会达到O(n*long n),不过很可惜看不懂,太菜了
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
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 Huge input, scanf is recommended.
Hint
Hint
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int mina=32767; 6 int village[105][105]; 7 int book[105]; 8 int sum; 9 int n; 10 void prime(int x) 11 { 12 for(int i=1;i<=n;i++) 13 book[i]=village[i][x]; 14 book[x]=0; 15 int flag=mina; 16 int k; 17 int step=1; 18 for(int i=1;i<n;i++){ 19 flag=mina; 20 for(int i=1;i<=n;i++) 21 if(book[i]!=0&&book[i]<flag) 22 { 23 flag=book[i]; 24 k=i; 25 } 26 27 sum+=book[k]; 28 book[k]=0; 29 for(int i=1;i<=n;i++) 30 if(village[i][k]<book[i]) 31 book[i]=village[i][k]; 32 } 33 } 34 int main() 35 { 36 37 while(scanf("%d",&n)&&n!=0) 38 { 39 sum=0; 40 int m=n*(n-1)/2; 41 int x,y; 42 for(int i=1;i<=m;i++){ 43 scanf("%d%d",&x,&y); 44 scanf("%d",&village[x][y]); 45 village[y][x]=village[x][y]; 46 } 47 for(int i=1;i<=n;i++) 48 village[i][i]=mina; 49 prime(1); 50 printf("%d ",sum); 51 } 52 return 0; 53 54 }