算法:Prime

 
  Prime算法解决的也是最小生成树的问题,思路很直观,开始时,任意选择一个点作为根,
然后选择离这个点最近的一个点和它连通,组成一个新的连通分量,再用新选的点更新其他未
被选择的点到已知连通分量的距离,更新完毕之后,选择一个离已知连通分量最近的点和已知
连通分量连通,组成新的连通分量,重复这个过程。直到所有点都被选中。
 
  Prime算法和Dijstra算法很像,不同点在于Prime更新的是从已知连通分量到其他各个
顶点的距离,Dijstra更新的是从源点到其他各个顶点的距离。

//表示边
struct Edge {
    int u;//起点
    int v;//终点
    int w;//权重
};

class Prime {
    vector<int> dis;
    vector<bool> book;
public:
    
    int minimumSpanningTreeSum(vector<Edge> &edges,int n) {
        if (edges.empty()) {
            return {};
        }
        book.resize(n, false);
        dis.resize(n,INT_MAX);
        vector<vector<int>> G(n,vector<int>(n));
        //初始化
        for(int i = 0;i < n;i++) {
            for(int j = 0;j < n;j++) {
                if(i == j) {
                    G[i][j] = 0;
                }
                else {
                    G[i][j] = INT_MAX;
                }
            }
        }
        //把边读入二维数组,方便后续访问
        for(int i = 0;i < edges.size();i++) {
            G[edges[i].u][edges[i].v] = edges[i].w;
            G[edges[i].v][edges[i].u] = edges[i].w;
        }
        //初始化dis数组,选取第一条的第一个顶点
        for(int i = 0;i < n;i++) {
            dis[i] = G[edges[0].u][i];
        }
        //选择第一个点
        book[edges[0].u] = true;
        int count = 1;
        int ans = 0;
        while (count < n) {
            int min = INT_MAX;
            int minV = -1;
            for(int i = 0;i < n;i++) {
                if(book[i] == false && dis[i] < min) {
                    min = dis[i];
                    minV = i;
                }
            }
            if (minV == -1) {
                //没找到,结束
                continue;
            }
            book[minV] = true;
            count++;
            ans += dis[minV];
            for(int k = 0;k < n;k++) {
                if(book[k] == false && dis[k] > G[minV][k]) {
                    dis[k] = G[minV][k];
                }
            }
        }
        
        return ans;
    }
};