当前位置: 首页 > news >正文

最小生成树的常用算法模板

生成树:有原图中的所有n个点,但只有n-1条边,且任意两个点能连通,不能有环
最小生成树:边权值之和最小的生成树

1、所有最小生成树算法

最小生成树问题一般都使用无向图,基本不会遇到有向图的问题。
在这里插入图片描述

2、朴素版 Prim 算法

稠密图就用Prim算法。

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

using namespace std;

const int N = 510, INF = 0x3f3f3f3f;

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

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];		// 注意更新 res 的位置,一定要在更新 dist 数组之前。若先更新dist,可能存在边权更小的自环,导致 dist[t] 被自环更新
        
        for (int j = 1; j <= n; j++) dist[j] = min(dist[j], g[t][j]);
        
        st[t] = true;
    }
    return res;
}

int main()
{
    cin >> n >> m;
    
    memset(g, 0x3f, sizeof g);
    
    while (m--)
    {
        int a, b, c;
        cin >> a >> b >> c;
        g[b][a] = g[a][b] = min(g[a][b], c);
    }
    
    int t = prim();
    
    if (t == INF) cout << "impossible" << endl;
    else cout << t << endl;
    
    return 0;
}

3、克鲁斯卡尔算法(Kruskal)

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

using namespace std;

const int N = 200010;

int n, m;
int p[N];

struct Edge
{
    int a, b, w;
    
    bool operator<(const Edge& W) const
    {
        return w < W.w;
    }
}edges[N];

int find(int x)
{
    if(p[x] != x) p[x] = find(p[x]);
    return p[x];
}

int main()
{
    cin >> n >> m;
    
    for (int i = 0; i < m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        edges[i] = {a, b, c};
    }
    
    sort(edges, edges + m);
    
    for (int i = 1; i <= n; i++) p[i] = i;
    
    int res = 0, cnt = 0;
    for (int i = 0; i < m; i++)
    {
        int a = edges[i].a, b = edges[i].b, w = edges[i].w;
        
        a = find(a), b = find(b);
        if (a != b)
        {
            p[a] = b;
            res += w;
            cnt++;
        }
    }
    
    if (cnt < n - 1) cout << "impossible" << endl;
    else cout << res << endl;
    
    return 0;
}

相关文章:

  • 一个服务器压力测试程序
  • 图论——二分图
  • 面向对象程序设计———组合、委托 与 继承
  • C++设计模式
  • C++ 嵌套类
  • CMake指令解析 set(CMAKE_CXX_FLAGS “$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c++11 -Wall -Wno-deprec
  • 记一个测试sylar服务器日志模块时遇到的一个非常奇怪的问题
  • syscall()
  • 记一个编写宏时的错误
  • C++中全局变量,静态变量,静态局部变量 的初始化和内存分配问题
  • C++ 模板实现单例模式
  • 《C++ Primer》 异常
  • C++父类和子类指针的相互赋值和转换
  • 算法设计与分析————期末死亡冲刺
  • 现代软件工程————期末死亡冲刺
  • Android框架之Volley
  • Android优雅地处理按钮重复点击
  • Angular Elements 及其运作原理
  • Apache Spark Streaming 使用实例
  • CentOS 7 修改主机名
  • CSS3 变换
  • CSS居中完全指南——构建CSS居中决策树
  • Java应用性能调优
  • KMP算法及优化
  • Laravel 实践之路: 数据库迁移与数据填充
  • leetcode讲解--894. All Possible Full Binary Trees
  • magento2项目上线注意事项
  • Object.assign方法不能实现深复制
  • React-redux的原理以及使用
  • Tornado学习笔记(1)
  • vue 配置sass、scss全局变量
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 正则表达式小结
  • nb
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #微信小程序(布局、渲染层基础知识)
  • (2)nginx 安装、启停
  • (4)Elastix图像配准:3D图像
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (C语言)球球大作战
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • **python多态
  • .net 简单实现MD5
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NET成年了,然后呢?
  • .net开发引用程序集提示没有强名称的解决办法