之前以为Prim的最小生成树算法不过如此。后来经过波波的指导发现原来我做的大部分最小生成树的题目里边用Prim都可以得到比较高的效率,而且代码比较少。而在《算法导论》里边Prim理论上可以达到O(E+Vlg(V))比Kruskal更优。先贴一个自己写的标程:
- #include <stdio.h>
- #include <memory.h>
- #include <algorithm>
- #include <iostream>
- using namespace std;
- // 最大值
- #define INF 99999999
- // 最多的边数
- #define N 500
- // 路径储存
- int road[N][N];
- int main()
- {
- int n,m,count;
- int i,j,k,l;
- int mink,min;
- scanf("%d",&m);
- while(m-- > 0) {
- scanf("%d",&n);
- for( i = 0; i < n; i++)
- for(j = 0; j < n; j++)
- cin >> road[i][j];
- //Prim最小生成树
- int res = 0;
- int lesscost[N];
- for(i = 0; i < n;i++)
- lesscost[i] = road[0][i];
- for( i = 1; i < n ;i++) {
- min = INF;
- for(j = 0; j < n ; j++)
- if(lesscost[j] > 0 && lesscost[j] < min) {
- min = lesscost[j];
- mink = j;
- }
- if(res < min)
- res = min;
- // 将刚加入集合的节点的所有边和现有边做一个比较,保留小的边
- for(j = 0; j < n;j++)
- if(lesscost[j] > road[mink][j])
- lesscost[j] = road[mink][j];
- }
- printf("%d/n",res);
- }
- }
这段代码的易读性不错(从波波那儿“参考”来的: > ),所以Prim就这样告一段落了。