C++ 算法学习——1.9 Kruskal算法

news2024/12/27 1:08:55

Kruskal算法是一种用于解决最小生成树(Minimum Spanning Tree)问题的贪婪算法。 

Kruskal算法步骤:

  1. 初始化:将图中的所有边按照权值从小到大进行排序。

  2. 创建并查集:为每个顶点创建一个集合,用于判断两个顶点是否在同一个连通分量中。

  3. 遍历排序后的边:从权值最小的边开始遍历。

  4. 检查边的两个顶点

    • 如果这两个顶点不在同一个连通分量中,则将它们加入最小生成树中,并合并它们的连通分量。
    • 如果这两个顶点已经在同一个连通分量中,则跳过这条边,以避免形成环路。
  5. 重复步骤4,直到最小生成树中有V-1条边(V为顶点数),此时最小生成树构建完成。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Edge {
    int src, dest, weight;
    Edge(int a,int b,int c):src(a),dest(b),weight(c){}
};

struct Graph {
    int V, E;
    vector<Edge> edges;
    Graph(int a,int b):V(a),E(b){}
};

int find(vector<int>& parent, int i) {
    while (parent[i] != i) {
        i = parent[i];
    }
    return i;
}

void Union(vector<int>& parent, int x, int y) {
    int xset = find(parent, x);
    int yset = find(parent, y);
    parent[xset] = yset;
}

void KruskalMST(Graph& graph) {
    int V = graph.V;
    vector<Edge> result;
    int e = 0, i = 0;

    sort(graph.edges.begin(), graph.edges.end(), [](const Edge& a, const Edge& b) {
        return a.weight < b.weight;
    });

    vector<int> parent(V);
    for (int v = 0; v < V; v++) {
        parent[v] = v;
    }

    while (e < V - 1 && i < graph.E) {
        Edge next_edge = graph.edges[i++];

        int x = find(parent, next_edge.src);
        int y = find(parent, next_edge.dest);

        if (x != y) {
            result.push_back(next_edge);
            Union(parent, x, y);
            e++;
        }
    }

    //cout << "Edges in the constructed MST:\n";
    for (const Edge& edge : result) {
        cout << edge.src << " -- " << edge.dest << " == " << edge.weight << endl;
    }
}

int main()
{
    int n,m;cin>>n>>m;
    Graph mygraph(n,m);
    for(int i=1;i<=m;i++)
    {
        int a,b,c;cin>>a>>b>>c;
        Edge p(a,b,c);
        mygraph.edges.push_back(p);
    }
    return 0;
}

 说明:

  • e < V - 1:这个条件是用来判断当前已经加入最小生成树的边数是否达到了顶点数减一,即 V - 1。在一个连通的图中,最小生成树的边数必定是顶点数减一。

  • i < graph.E:这个条件是用来确保遍历完所有的边。graph.E 表示图中边的总数,i 是当前处理到的边的索引。这个条件保证在所有边都遍历完之前继续尝试找到最小生成树的边。


P1. 洛谷p3366最小生成树 

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
int ans=0;
struct Edge {
    int src, dest, weight;
    Edge(int a,int b,int c):src(a),dest(b),weight(c){}
};

struct Graph {
    int V, E;
    vector<Edge> edges;
    Graph(int a,int b):V(a),E(b){}
};

int find(vector<int>& parent, int i) {
    while (parent[i] != i) {
        i = parent[i];
    }
    return i;
}

void Union(vector<int>& parent, int x, int y) {
    int xset = find(parent, x);
    int yset = find(parent, y);
    parent[xset] = yset;
}

void KruskalMST(Graph& graph) {
    int V = graph.V;
    vector<Edge> result;
    int e = 0, i = 0;

    sort(graph.edges.begin(), graph.edges.end(), [](const Edge& a, const Edge& b) {
        return a.weight < b.weight;
    });

    vector<int> parent(V);
    for (int v = 0; v < V; v++) {
        parent[v] = v;
    }

    while (e < V - 1 && i < graph.E) {
        Edge next_edge = graph.edges[i++];

        int x = find(parent, next_edge.src);
        int y = find(parent, next_edge.dest);

        if (x != y) {
            result.push_back(next_edge);
            Union(parent, x, y);
            e++;
            ans+=next_edge.weight;
        }
    }
    if(e!=V-1) cout<<"orz";
    else cout<<ans; 

    //cout << "Edges in the constructed MST:\n";
    //for (const Edge& edge : result) {
        //cout << edge.src << " -- " << edge.dest << " == " << edge.weight << endl;
    //}
}

int main()
{
    int n,m;cin>>n>>m;
    Graph mygraph(n,m);
    for(int i=1;i<=m;i++)
    {
        int a,b,c;cin>>a>>b>>c;
        Edge p(a-1,b-1,c);
        mygraph.edges.push_back(p);
    }
    KruskalMST(mygraph);
    return 0;
}

P2. 洛谷p1194买礼物

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;
int ans=0;
struct Edge {
    int src, dest, weight;
    Edge(int a,int b,int c):src(a),dest(b),weight(c){}
};

struct Graph {
    int V, E;
    vector<Edge> edges;
    Graph(int a,int b=0):V(a),E(b){}
};

int find(vector<int>& parent, int i) {
    while (parent[i] != i) {
        i = parent[i];
    }
    return i;
}

void Union(vector<int>& parent, int x, int y) {
    int xset = find(parent, x);
    int yset = find(parent, y);
    parent[xset] = yset;
}

int KruskalMST(Graph& graph) {
    int V = graph.V;
    graph.E = graph.edges.size();
    vector<Edge> result;
    int e = 0, i = 0;

    sort(graph.edges.begin(), graph.edges.end(), [](const Edge& a, const Edge& b) {
        return a.weight < b.weight;
    });

    vector<int> parent(V);
    for (int v = 0; v < V; v++) {
        parent[v] = v;
    }

    while (e < V - 1 && i < graph.E) {
        Edge next_edge = graph.edges[i++];

        int x = find(parent, next_edge.src);
        int y = find(parent, next_edge.dest);

        if (x != y) {
            result.push_back(next_edge);
            Union(parent, x, y);
            e++;
            ans+=next_edge.weight;
        }
    }
    return ans;

    //cout << "Edges in the constructed MST:\n";
    //for (const Edge& edge : result) {
        //cout << edge.src << " -- " << edge.dest << " == " << edge.weight << endl;
    //}
}

int main()
{
    int n,m;cin>>n>>m;
    Graph mygraph(m);
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<m;j++)
        {
            int weight;cin>>weight;
            if(weight)
            {
                Edge p(i,j,min(n,weight));
                mygraph.edges.push_back(p);
            }
            if(!weight)
            {
                Edge p(i,j,n);
                mygraph.edges.push_back(p);
            }
        }
    }
    cout<<n+KruskalMST(mygraph);
    return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2217171.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中国灌溉农田空间分布

针对全国灌溉农田空间分布数据缺失的现状&#xff0c;融合MODIS植被指数和统计数据生成MIrAD-GI临时灌溉数据集&#xff0c;再利用约束统计和协同绘图方法将其与中国区域现有灌溉数据进行集成、整合&#xff0c;生成了2000-2019年中国逐年灌溉农田分布数据集&#xff08;500米空…

5、JavaScript(四)

25.ajax : 前端向后端异步的取数据而无需刷新页面的技术 1 公司中的整体工作流程 1、项目开发的流程 每个职位该做的工作&#xff1a; 产品经理&#xff1a;提需求的 与客户沟通 画出原型图给程序员使用 UI设计师&#xff1a;美化 替换UI框架&#xff1a;antd element-ui e…

python将照片集导出成视频

shigen坚持更新文章的博客写手&#xff0c;记录成长&#xff0c;分享认知&#xff0c;留住感动。个人IP&#xff1a;shigen 背景 一个安静的下午&#xff0c;看着电脑里乱七八糟的照片&#xff0c;有大有小&#xff0c;宽高不一&#xff0c;突然想找个方式把他们统一起来&…

SketchUp Pro 2024 for Mac 3D建模 草图设计大师软件安装【保姆级教程,简单小白轻松上手】

Mac分享吧 文章目录 SketchUp Pro 3D建模 草图设计大师软件 安装完成&#xff0c;软件打开效果一、Mac中安装SketchUp Pro 3D建模 草图设计大师软件——v241️⃣&#xff1a;下载软件2️⃣&#xff1a;安装软件&#xff0c;将安装包从左侧拖入右侧文件夹中3️⃣&#xff1a;应…

【数据结构】7道经典链表面试题

目录 1.返回倒数第K个节点【链接】 代码实现 2.链表的回文结构【链接】 代码实现 3.相交链表【链接】 代码实现 4.判断链表中是否有环【链接】 代码实现 常见问题解析 5.寻找环的入口点【链接】 代码实现1 代码实现2 6.随机链表的复制【链接】 代码实现 7.顺序…

DS堆的特性和实现(9)

文章目录 前言一、堆的概念和结构二、堆的调整算法向下调整算法向上调整算法两种算法建堆的时间复杂度 三、堆的实现结构体定义初始化和销毁堆的插入堆的删除挪移数据覆盖删除首尾交换再删除 获取堆顶元素获取有效数据个数判断是否为空 总结 前言 继续&#xff0c;本篇较难   …

我的创作纪念日-365天的感悟

时光荏苒&#xff0c;岁月如梭。转眼间&#xff0c;自己在CSDN注册已经整整15个年头了。回想起当初&#xff0c;还是个满怀憧憬、对未来充满无限好奇的学生哥。如今&#xff0c;虽然身份和角色发生了诸多变化&#xff0c;但CSDN始终陪伴着我&#xff0c;见证了我的成长与蜕变。…

JavaWeb环境下的Spring Boot在线考试系统开发

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理基于JavaWeb技术的在线考试系统设计与实现…

深入探讨C++多线程性能优化

深入探讨C多线程性能优化 在现代软件开发中&#xff0c;多线程编程已成为提升应用程序性能和响应速度的关键技术之一。尤其在C领域&#xff0c;多线程编程不仅能充分利用多核处理器的优势&#xff0c;还能显著提高计算密集型任务的效率。然而&#xff0c;多线程编程也带来了诸…

OpenAI的新功能Canvas,效果还不错

时隔两年&#xff0c;ChatGPT终迎来界面全新升级&#xff01; 这一次&#xff0c;OpenAI官宣推出类似 Anthropic 的 Artifacts 的界面交互功能 canvas&#xff0c;并称这是一种使用 ChatGPT 写作和编程的新方式。不论是写作&#xff0c;还是编码&#xff0c;都可以开启全新的交…

什么!我上传的文件不见了?

什么&#xff01;我上传的文件不见了? 前言&#xff1a; 最近在实现一个文件上传功能时使用了异步处理&#xff0c;但是在异步处理文件时&#xff0c;却提示NoSuchFileException错误。简化代码如下&#xff1a; PostMapping("/upload")void testFileUpload(Reques…

Flume抽取数据(包含自定义拦截器和时间戳拦截器)

flume参考网址&#xff1a;Flume 1.9用户手册中文版 — 可能是目前翻译最完整的版本了https://flume.liyifeng.org/?flagfromDoc#要求&#xff1a; 使用Flume将日志抽取到hdfs上&#xff1a;通过java代码编写一个拦截器&#xff0c;将日志中不是json数据的数据过滤掉&#xf…

学习文档10/16

MySQL 字符集&#xff1a; MySQL 支持很多种字符集的方式&#xff0c;比如 GB2312、GBK、BIG5、多种 Unicode 字符集&#xff08;UTF-8 编码、UTF-16 编码、UCS-2 编码、UTF-32 编码等等&#xff09;。 查看支持的字符集 你可以通过 SHOW CHARSET 命令来查看&#xff0c;支持…

一次性理清Environment体系

在Spring中&#xff0c;我们可以通过配置文件等方式去进行一些属性值的配置&#xff0c;比如通过Value注解去获取到对应的属性值&#xff0c;又或者说是想在程序运行时获取系统环境变量&#xff0c;类似的这些操作其实都是去获取一些配置数据&#xff0c;所以在Spring中对这些数…

C++ | Leetcode C++题解之第486题预测赢家

题目&#xff1a; 题解&#xff1a; class Solution { public:bool PredictTheWinner(vector<int>& nums) {int length nums.size();auto dp vector<int>(length);for (int i 0; i < length; i) {dp[i] nums[i];}for (int i length - 2; i > 0; i-…

基于SpringBoot+Vue+uniapp的在线招聘平台的详细设计和实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

喜报丨财富通科技荣获ISO9001、ISO27001及ISO20000三项国际认证

近日&#xff0c;财富通科技成功通过ISO9001、ISO27001及ISO20000三项国际标准认证。这标志着公司在质量管理体系、信息安全管理体系以及信息技术服务管理体系建设方面达到了国际认可的标准。 ISO9001认证表明财富通科技在软件开发、技术服务和项目管理等方面建立了一套完善的…

带你学习如何编写一篇API详设文档以及给新人提点建议

文章目录 前言先认清一个问题详设文档如何写先看文档脉络详设文档分析需求背景方案概述API定义安全设计性能设计缓存与数据库 总结 前言 这篇文章带读者了解软件开发项目中一个需求的开发详设文档主要包括哪些内容&#xff0c;其中重点会给读者分析API设计的规范&#xff0c;相…

推荐算法的学习

文章目录 前言1、模型1.1 从本领域模型的发展历史中学习1.1.1 在历史中总结发展规律和趋势1.1.2 发现模型之间的共性&#xff0c;方便记忆 1.2 从其他领域的发展中学习1.2.1 注意力机制1.2.2 残差网络 1.3 实践该怎么办&#xff1f; 2、 特征2.1 数据源的选择与建立2.2 特征构造…

react18中实现简易增删改查useReducer搭配useContext的高级用法

useReducer和useContext前面有单独介绍过&#xff0c;上手不难&#xff0c;现在我们把这两个api结合起来使用&#xff0c;该怎么用&#xff1f;还是结合之前的简易增删改查的demo&#xff0c;熟悉vue的应该可以看出&#xff0c;useReducer类似于vuex&#xff0c;useContext类似…