代码编织梦想

在最小生成树问题里,正边和负边都没问题

朴素版prim算法 时间复杂度O(n^2)

生成树:每一次选中的t点,它和集合的距离对应的那条边,就是生成树的一条边

算法流程和dijkstra算法非常相似 

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 510,INF = 0x3f3f3f3f;

int n,m;
int g[N][N];
int dist[N];
bool vis[N];

int prim(){
    memset(dist,0x3f,sizeof dist);
    dist[1] = 0;
    int res = 0;
    for(int i = 1; i <= n; i ++ ){
        int t = -1;
        for(int j = 1; j <= n; j ++ ){
            if(!vis[j] && (t == -1 || dist[j] < dist[t])){
                t = j;
            }
        }
            vis[t] = true;
            if(dist[t] == INF) return 0;
            //res的更新要先于dist[t]的更新,因为如果出现负环,就可能导致dist[t]被错误更新,从而导致res的错误
            res += dist[t];
            for(int j = 1; j <= n; j ++ ){
                /* 与dijkstra
                dist[j] = min(dist[j],dist[t] + g[t][j]);
                不同的是,prim是与g[t][j]作比较,
                因为dijkstra的dist[j]表示的是j与原点的最短距离,而prim算法中
                dist[j]表示的是j点与集合的最短距离 */
                dist[j] = min(dist[j],g[t][j]);
            }
            vis[t] = true;
    }
    return res;
}

int main(){
    cin >> n >> m;
    memset(g, 0x3f, sizeof g);
    while(m -- ){
        int u,v,w;
        cin >> u >> v >> w;
        //无向图是特殊的有向图,建边时只要建一条从a到b的,再建一条从b到a的就可以了
        g[u][v] = g[v][u] = min(g[u][v],w);
    }
    int t = prim();
    if(!t) cout << "impossible" << endl;
    else cout << t << endl;
    return 0;
}

堆优化版prim几乎不会用到,一般直接用kruskal就可以解决。堆优化的prim对比kruskal没有明显优势,还比较难写,故此处不贴模板。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/2301_76553467/article/details/137156846

【图论】Prim算法求最小生成树详解-爱代码爱编程

Prim算法 一、算法学习前先要知道1.最小生成树(必须了解)2.Dijkstra算法(建议了解)二、算法实现步骤1.初始化2.寻找三、算法的代码实现1.朴素Prim算法实现2.Prim算法优先队列优化 一、算法学习前先要知道 1.最小生成树(必须了解) 对于无向图G(V,E),连接所有点V以及边集是E的子集的树称为G的生成树。而边的权值和

搜索与图论 Prim算法求最小生成树-爱代码爱编程

Prim算法求最小生成树 给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。 由 V 中的全部 n 个顶点和 E 中 n−1

搜索与图论:prim算法求最小生成树—prim_奋斗吧!骚年!的博客-爱代码爱编程

AcWing 858. Prim算法求最小生成树 给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。 由 V 中的全部 n 个顶

prim算法求最小生成树_eliauk-gx的博客-爱代码爱编程

一.最小生成树 给定一张边带无权的无向图G = (V, E), n = |V|, m = |E|。由V中全部n个顶点和E中n - 1条边构成的无向连通子图被称为G的一课生成树。边的权值之和最小的生成树被称为无向图的最小生成

(二)bsq,bil,bip存储格式的相互转换算法-爱代码爱编程

环境:Windows10专业版 + IDEA2021.2.3 + jdk11.0.1 + GDAL(release-1928-x64-gdal-3-5-2-mapserver-8-0-0) 系列文章: (一)Python+GDAL实现BSQ,BIP,BIL格式的相互转换 (二)BSQ,BIL,BIP存储格式的相互转换算法 (三

算法-爱代码爱编程

并查集合字面意思,合并,查询,集合。 why 为什么要使用它,什么题适用于这个算法。 一般当我们在考虑图联通的时候就可以考虑一下使用并查集。他跟图密切相关。 what 并查集主要是什么。 我们一般使用一个集合来存放图中的各个节点。 然后初始化让这个集合里的元素是他自己,这里形象的形容让他自己成为自己的领导。 然后当一个节点要和另一个节点相连

1.5-爱代码爱编程

59. 螺旋矩阵II ★★   力扣题目链接,给你一个正整数 n ,生成一个包含 1 到 n

算法打卡day21(开始回溯)-爱代码爱编程

今日任务: 1)77.组合 77.组合 题目链接:77. 组合 - 力扣(LeetCode) 文章讲解:代码随想录 (programmercarl.com) 视频讲解:带你学透回溯算法-组合问题(对应力扣题目:77.组合)| 回溯法精讲!哔哩哔哩bilibili 带你学透回溯算法-组合问题的剪枝操作(对应力扣题目:77.组合)| 回

算法打卡day17-爱代码爱编程

今日任务: 1)654.最大二叉树 2)617.合并二叉树 3)700.二叉搜索树中的搜索 4)98.证二叉搜索树 654.最大二叉树 题目链接:654. 最大二叉树 - 力扣(LeetCode) 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下: 1.二叉树的根是数组中的最大元素。 2.左子树是通

代码随想录算法训练营第二十三天(二叉树9)|669. 修剪二叉搜索树、108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树(java)-爱代码爱编程

文章目录 669. 修剪二叉搜索树解题思路源码 108. 将有序数组转换为二叉搜索树解题思路源码 538. 把二叉搜索树转换为累加树解题思路源码 669. 修剪二叉搜索树 给你

java八股文(算法)-爱代码爱编程

Java八股文の算法 算法 算法 逆序输出字符串 题目描述:输入一个字符串,要求逆序输出。 public static String reverseString(String s) { S