前几篇文章,发的都是Prim算法差不多O(n^3)的时间复杂度,其实标准的Prim算法,时间复杂度是O(n^2),所以需要改进,Prim算法就是U集合的增大和V-U集合的减少,总共要进行n-1次地把点从 V-U集合添加到U集合中,直到U集合中含有n个点为止。
如图:
- #include<iostream>
- #include<cstdio>
- #include<vector>
- #include<string>
- #include <cstdlib>
- using namespace std;
- const int MAX = 2001;
- const int INF = 100;
- int c[MAX][MAX];
- int closet[MAX];//记录的是V-U集合连接到U集合中,最小的边,包含在U中的顶点
- int lowcost[MAX];
- char ss[MAX][7];
- bool flag[MAX];
- int Prim(int n)
- {
- int i, j, k, ans = 0, pair = 0;
- flag[1] = true;
- for(i = 2; i <= n; i++)
- {
- lowcost[i] = c[1][i];
- closet[i] = 1;
- flag[i] = false;
- }
- for(i = 1; i < n; i++)
- {
- j = 1;
- int min = INF;
- //遍历V-U集合,找到最小的lowcost
- for(k = 2; k <=n; k++)
- {
- if(lowcost[k] < min && !flag[k])
- {
- min = lowcost[k];
- j = k;
- }
- }
- flag[j] = true;
- //j<--->closet[j]表示新加入的这条边的长度
- ans += c[j][closet[j]];
- //重新计算V-U集合 到 U集合之间的 lowcost
- for(k = 2; k <= n; k++)
- {
- if(c[j][k] < lowcost[k] && !flag[k])
- {
- lowcost[k] = c[j][k];
- //为以后加入到U集合预先准备 k<--->closet[k]表示新加入的一条边
- closet[k] = j;
- }
- }
- }
- return ans;
- }