• 随想录 Day 71 最小生成树 prim算法 kruskal算法


    随想录 Day 71 最小生成树 prim算法 kruskal算法

    53. 寻宝(第七期模拟笔试)

    时间限制:1.000S 空间限制:128MB
    题目描述
    在世界的某个区域,有一些分散的神秘岛屿,每个岛屿上都有一种珍稀的资源或者宝藏。国王打算在这些岛屿上建公路,方便运输。

    不同岛屿之间,路途距离不同,国王希望你可以规划建公路的方案,如何可以以最短的总公路距离将 所有岛屿联通起来(注意:这是一个无向图)。

    给定一张地图,其中包括了所有的岛屿,以及它们之间的距离。以最小化公路建设长度,确保可以链接到所有岛屿。

    输入描述
    第一行包含两个整数V 和 E,V代表顶点数,E代表边数 。顶点编号是从1到V。例如:V=2,一个有两个顶点,分别是1和2。

    接下来共有 E 行,每行三个整数 v1,v2 和 val,v1 和 v2 为边的起点和终点,val代表边的权值。

    输出描述
    输出联通所有岛屿的最小路径总距离

    prim算法精讲

    prim算法核心就是三步,我称为prim三部曲,大家一定要熟悉这三步,代码相对会好些很多:

    第一步,选距离生成树最近节点

    第二步,最近节点加入生成树

    第三步,更新非生成树节点到生成树的距离(即更新minDist数组)

    # include 
    # include 
    using namespace std;
    int v, e;
    int main() {
        cin >> v >> e;
        vector<vector<int> > map(v +1, vector<int>(v+1, 100001));
        for(int i = 0; i < e; i++ ) {
            int start, weight, end;
            cin>> start>> end>> weight;
            map[start][end] = weight;
            map[end][start] = weight;
        }
        // for(int i = 0; i < v; i++) {
        //     for (int j = 0; j < v; j++) {
        //         cout<< map[i][j]<< " ";
        //     }
        //     cout << endl;
        // }
        vector<bool> inTree(v+1, false);
        vector<int> minDis(v+1, 100001);
        inTree[1] = true;
        int cur = 1;
        int res = 0;
        int inIndex = 1;
        
        for (int t = 1 ; t < v; t++) {
            int minD = 100001;
            for (int i = 1; i <= v; i++) {
                //cout << i << "original "<< minDis[i] << endl;
                //cout<< cur << " "<< map[cur][i] <<" "<< i << endl;
                if (inTree[i] != true) {
                    minDis[i] = min(minDis[i], map[cur][i]);
                    if (minDis[i] < minD) {
                        inIndex = i;
                        minD = minDis[i];
                    }
                    //cout << i << "changed "<< minDis[i] << endl;
                }
               
            }
            //cout<< inIndex << " " << minD << endl;
            
            res += minD;
            inTree[inIndex] = true;
            cur = inIndex;
        }
        
        cout<< res;
    }
    

    kruskal算法精讲

    kruscal的思路:

    边的权值排序,因为要优先选最小的边加入到生成树里

    遍历排序后的边

    如果边首尾的两个节点在同一个集合,说明如果连上这条边图中会出现环

    如果边首尾的两个节点不在同一个集合,加入到最小生成树,并把两个节点加入同一个集合

    # include 
    # include 
    # include 
    using namespace std;
    int v, e;
    class Edge{
        public:
        int v1,v2, weight;
        
    };
    class cmp {
        public:
        bool operator()(const Edge &a, const Edge &b ) {
            return a.weight < b.weight;
        }
    };
    class DisjointSet {
        public:
        vector<int> father;
        DisjointSet(int n) {
            father.resize(n+1, 0);
            for (int i = 0; i < n+1; i++) {
                father[i] = i;
            }
        }
        int find(int u) {
            return father[u] == u ? u : father[u] = find(father[u]);
        }
        bool isSame(int u, int v) {
            u = find(u);
            v = find(v);
            return u == v;
        }
        void join(int u, int v) {
            u = find(u);
            v = find(v);
            if (u == v) return;
            father[u] = v;
        }
    };
    int main() {
       cin>> v >> e;
       vector<Edge> edges(e);
       for (int i = 0; i < e; i++) {
           cin>> edges[i].v1 >> edges[i].v2>>edges[i].weight;
       }
       sort(edges.begin(), edges.end(), cmp());
       
    //   for (int i = 0; i < e; i++) {
    //       cout<< edges[i].v1 <<" "<< edges[i].v2<<" "<< edges[i].weight<< endl;;
    //   }
        DisjointSet sets(v);
        int res = 0;
        for (Edge edge : edges) {
            if (sets.isSame(edge.v1, edge.v2)) continue;
            else {
                res += edge.weight;
                sets.join(edge.v1, edge.v2);
            }
        }
        cout << res;
    }
    
  • 相关阅读:
    Lecture 5 Threads(线程)
    Nginx的安全控制
    使用React和ResizeObserver实现自适应ECharts图表
    LeetCode977——有序数组的平方
    力扣(LeetCode)222. 完全二叉树的节点个数(2022.08.10)
    如何加快生产型人工智能的性能?
    leetcode/子串中不能有重复字符的最长子串
    【通信原理笔记】【二】随机信号分析——2.1 随机过程与其相关函数
    十大经典排序算法——java语言
    Notepad++插件 Hex-Edit
  • 原文地址:https://blog.csdn.net/weixin_44645059/article/details/140009470