【刷题】图论——最小生成树:Prim、Kruskal【模板】

假设有n个点m条边。

Prim适用于邻接矩阵存的稠密图,时间复杂度是 O ( n 2 ) O(n^2) O(n2),可用堆优化成 O ( n l o g n ) O(nlogn) O(nlogn)。

Kruskal适用于稀疏图,n个点m条边,时间复杂度是 m l o g ( m ) mlog(m) mlog(m)。

Prim:遍历n次,每次选择连通块和外面的点 到连通块距离最短 的一条边,并将该边对应点加入连通块中,更新其他店到连通块的距离

Kruskal:将所有边权从小到大排序,依次枚举每条边(a和b相连,边权w),如果发现目前a和b不在一个连通块内,将a和b加入连通块中。

题目

题目链接

Prim

cpp 复制代码
#include <iostream>
#include <cstring>

using namespace std;
const int N = 110;
int n;
int w[N][N];
int dist[N]; // 外界每个点和当前连通块直接相连的边的最小值
bool st[N]; // 是否加入连通块

int prim() {
    int res = 0;
    memset(dist, 0x3f, sizeof(dist));
    dist[1] = 0;
    for (int i = 0; i < n; i ++ ) {
        int t = -1; // 不在连通块内的点里面,距离最小的点
        for (int j = 1; j <= n; j ++ ) {
            if (!st[j] && (t == -1 || dist[t] > dist[j])) { // j不在连通块里且或j距离更小
                t = j;
            }
        }
        res += dist[t];
        st[t] = true;
        for (int j = 1; j <= n; j ++ ) dist[j] = min(dist[j], w[t][j]); // 更新所有t能到的距离
    }
    return res;
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= n; j ++ ) {
            scanf("%d", &w[i][j]);
        }
    }
    cout << prim() << endl;
}

Kruskal

cpp 复制代码
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 110;
const int M = 10010;

struct Edge {
    int a, b, w;
    bool operator< (const Edge &t) const {
        return w < t.w;
    }
};

Edge e[M];
int p[N];
int n, w, m;

int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
int kruskal() {
    for (int i = 1; i <= n; i ++ ) p[i] = i;
    sort(e, e + m);
    int res = 0;
    for (int i = 0; i < m; i ++ ) {
        int a = find(e[i].a);
        int b = find(e[i].b);
        if (a != b) {
            p[a] = b;
            res += e[i].w;
        }
    }
    return res;
}
int main() {
    scanf("%d", &n);
    m = n * n;
    for (int i = 0; i < n; i ++ ) {
        for (int j = 0; j < n; j ++ ) {
            scanf("%d", &w);
            e[i * n + j] = {i + 1, j + 1, w};
        }
    }
    cout << kruskal() << endl;
}
相关推荐
kkeeper~4 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
wabs6665 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964135 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
嗝o゚6 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本6 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Ulyanov8 小时前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真
数据科学小丫8 小时前
特征工程处理
人工智能·算法·机器学习
z落落8 小时前
C#参数区别
java·算法·c#
c238569 小时前
vector(下)
数据结构·算法
z落落9 小时前
C# 冒泡排序+选择排序 + Array.Sort 自定义排序
数据结构·算法