zoukankan      html  css  js  c++  java
  • 最小生成树—Prim算法

    首先我们定义带权图 GG 的顶点集合为 VV,接着我们再定义最小生成树的顶点集合为 UU,初始集合 UU 为空。接着执行以下操作:

    1. 首先我们任选一个顶点 xx,加入集合 UU,并记录每个顶点到当前最小生成树的最短距离。

    2. 选择一个距离当前最小生成树最近的、且不属于集合 UU 的顶点 vv(如果有多个顶点 vv,任选其一即可),将顶点 vv 加入集合 UU,并更新所有与顶点 vv 相连的顶点到当前最小生成树的最短距离。

    3. 重复第二步操作,直至集合 UU 等于集合 VV

    最小生成树构造完毕,集合 UU 记录了最小生成树的所有边。

    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <queue>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    struct Edge {
        int vertex, weight;
    };
    class Graph {
    private:
        int n;
        bool * visited;
        vector<Edge> * edges;
    public:
        int * dist;
        Graph (int input_n) {
            n = input_n;
            edges = new vector<Edge>[n];
            dist = new int[n];
            visited = new bool[n];
            memset(visited, false, n * sizeof(bool));
            memset(dist, 0x3f, n * sizeof(int));
        }
        ~Graph() {
            delete[] dist;
            delete[] visited;
            delete[] edges;
        }
        void insert(int x, int y, int weight) {
            edges[x].push_back(Edge{y, weight});
            edges[y].push_back(Edge{x, weight});
        }
        int prim(int v) {
            int total_weight=0;
            dist[v]=0;
            for(int i=0;i<n;i++){
               int min_dist=INF,min_vertex;//min_dist保存到当前树的最小距离,min_vertex保存该节点
                for(int j=0;j<n;j++){
                    if(!visited[j]&&dist[j]<min_dist){
                        min_dist=dist[j];
                        min_vertex=j;
                    }   
                }
                total_weight+=min_dist;
                visited[min_vertex]=1;
                for(Edge &j:edges[min_vertex]){//更新权值
                    if(!visited[j.vertex]&&j.weight<dist[j.vertex]){
                        dist[j.vertex]=j.weight;
                    }
                }
            }
            return total_weight;
        }
    };
    
    
    int main() {
        int n, m;
        cin >> n >> m;
        Graph g(n);
        for (int i = 0; i < m; i++) {
            int a, b, c;
            cin >> a >> b >> c;
            g.insert(a, b, c);
        }
        cout << g.prim(0) << endl;
        return 0;
    }

  • 相关阅读:
    判断两个对象是否相同
    参数的修饰符
    异常处理
    类型转换
    值类型和引用类型
    抽象方法实现计算器
    静态
    多态
    访问修饰符
    面向对象三大特性
  • 原文地址:https://www.cnblogs.com/nickqiao/p/7583353.html
Copyright © 2011-2022 走看看