acwing算法基础之搜索与图论--prim算法

目录

  • [1 基础知识](#1 基础知识)
  • [2 模板](#2 模板)
  • [3 工程化](#3 工程化)

1 基础知识

朴素版prim算法的关键步骤:

  1. 初始化距离数组dist,将其内的所有元素都设为正无穷大。
  2. 定义集合S,表示生成树。
  3. 循环n次:找到不在集合S中且距离集合S最近的结点t,用它去更新剩余结点到集合S的距离。
  4. 最小生成树建立完毕,边长之和等于每次的d[t]之和。

朴素版prim算法的时间复杂度为O(n^2),它用来解决稠密图的最小生成树问题。

2 模板

cpp 复制代码
int n;      // n表示点数
int g[N][N];        // 邻接矩阵,存储所有边
int dist[N];        // 存储其他点到当前最小生成树的距离
bool st[N];     // 存储每个点是否已经在生成树中


// 如果图不连通,则返回INF(值是0x3f3f3f3f), 否则返回最小生成树的树边权重之和
int prim()
{
    memset(dist, 0x3f, sizeof dist);

    int res = 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]))
                t = j;

        if (i && dist[t] == INF) return INF;

        if (i) res += dist[t];
        st[t] = true;

        for (int j = 1; j <= n; j ++ ) dist[j] = min(dist[j], g[t][j]);
    }

    return res;
}

3 工程化

题目1:求最小生成树。

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

using namespace std;

const int N = 510;
int g[N][N];
int d[N];
bool st[N];
int n, m;

void prim() {
    memset(d, 0x3f, sizeof d);
    
    int res = 0;
    for (int i = 0; i < n; ++i) {//n次循环
        //找到不在集合S且距离集合S最小的结点
        int t = -1;
        for (int j = 1; j <= n; ++j) {
            if (!st[j] && (t == -1 || d[t] > d[j])) {
                t = j;
            }
        }
        
        if (i && d[t] == 0x3f3f3f3f) {
            cout << "impossible" << endl;
            return;
        }
        
        st[t] = true;
        if (i) res += d[t];
        
        //用t去更新其它结点
        for (int j = 1; j <= n; ++j) {
            if (d[j] > g[t][j]) {
                d[j] = g[t][j];
            }
        }
    }
    
    cout << res << endl;
    return;
}

int main() {
    cin >> n >> m;
    
    memset(g, 0x3f, sizeof g);
    int a, b, c;
    while (m--) {
        cin >> a >> b >> c;
        g[a][b] = min(g[a][b], c);
        g[b][a] = min(g[b][a], c);
    }
    
    prim();
    
    return 0;
}
相关推荐
机器学习之心1 分钟前
异常检测 | 高斯分布拟合算法异常数据检测(Matlab)
算法·数学建模·matlab·异常数据检测
Ning_.32 分钟前
力扣第 66 题 “加一”
算法·leetcode
kitesxian33 分钟前
Leetcode437. 路径总和 III(HOT100)
算法·深度优先
YSRM35 分钟前
异或-java-leetcode
java·算法·leetcode
木向39 分钟前
leetcode:222完全二叉树的节点个数
算法·leetcode
Ning_.1 小时前
力扣第 67 题 “二进制求和”
算法·leetcode
IT 青年1 小时前
数据结构 (11)串的基本概念
数据结构
bbppooi1 小时前
堆的实现(完全注释版本)
c语言·数据结构·算法·排序算法
FFDUST1 小时前
C++ 优先算法 —— 无重复字符的最长子串(滑动窗口)
c语言·c++·算法·leetcode
m0_738054562 小时前
【leetcode】全排列 回溯法
c++·算法·leetcode·回溯法