算法总结——Prim
Prim:
复杂度:O(n^2)
用途:最小生成树算法,求一点到所有的位置之和的最小值,不是形成环,是把所有顶点连在一起的最短路
适用条件:
步骤:跟Dijkstra出奇的相似,只是prim把d和p都变成一个k数组(- -其实一样好吗)而且Dijkstra是第一个for为了记录下标,而prim是为了记录下标和记录最小值(- -其实也是一样好吗),不过prim的第二个for是已经确定了走了一条路,然后是从这条路出发,看从这个定点出发和原来的最短路径相比哪个短,如果从这个顶点出发的更短,那么更新k,,而Dijkstra只是单纯的把地图优化。
模板:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int inf = 0x3f3f3f3f,MAX = 3000; int map[MAX][MAX], k[MAX]; void prim (int map[MAX][MAX],int n){ int min1,m,ans = 0; for(int i = 1; i <= n ;i++) k[i] = map[1][i]; for(int i = 1; i < n ;i++){ int min1 = inf; m = 0; for(int j = 1; j <= n ;j++){ if(k[j] < min1 && k[j]!=0){ min1 = k[j]; m = j; } } k[m] = 0; ans +=min1; for(int j = 1; j <= n ; j++){ if(k[j] > map[m][j] && k[j]!=0) k[j] = map[m][j]; } } printf("%d\n",ans); } int main() { int n,a; while(~scanf("%d",&n)&&n){ for(int i = 1; i <= n ;i++) for(int j = 1; j <= n ;j++) scanf("%d",&map[i][j]); prim(map,n); } return 0; }