Prim算法

算法流程:

(1)初始化所有点到已加入点集合的距离为INF。

(2)做n次遍历,每次从未加入集合的点中找到离集合距离最小的点,将该点加入到生成树中。

(3)在每次循环中一旦找到距离最小的点后,使用该点来更新集合外的点到集合的距离。

使用的数据结构:领接矩阵(稠密图)

代码如下:

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

using namespace std;

const int N = 510, INF = 0x3f3f3f3f;

int g[N][N];
int dist[N]; // 表示每个点到集合的距离
bool st[N];

int n, m;

int prim()
{
    // 初始化所有距离为INF
    memset(dist, 0x3f, sizeof dist);
    // 迭代N次,找到N个点
    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;
        }
        // 如果不是第一个点,且离集合的距离为INF,则表示该图为非联通图
        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;
    
}

int main()
{
    cin >> n >> m;
    memset(g, 0x3f, sizeof g);
    
    while(m--)
    {
        int u, v, w;
        cin >> u >> v >> w;
        g[u][v] = g[v][u] = min(g[u][v], w);
    }
    
    int res = prim();
    
    if(res > INF / 2) puts("impossible");
    else cout << res << endl;
    
    return 0;
}
复制代码

 

posted @   krystalZ2021  阅读(64)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示