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

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

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.mrgr.cn/news/52123.html

相关文章:

  • 数据结构(栈)
  • 第二天 Python基础语法
  • Python入门:轻松学会Python的*args和**kwargs
  • MPI程序实例:二维热传导方程(上)
  • JsonObject (JSON 数据中的一个对象)
  • 波兰式与逆波兰式【1】
  • 苍穹外卖学习笔记(二十四)
  • 人工智能 | MetaLlama大模型
  • 通用代码生成器与编程初学者的“第一个系统”
  • 【python】生成环境下依赖的关系拓扑图
  • Spring Boot环境下的图书进销存管理系统
  • 看了大厂用AI审简历,我才发现社会的残酷真相!今年的秋招太可怕了
  • etcd集群修复异常节点
  • SpringBoot长江驾校学员预约系统-计算机毕业设计源码86072
  • 从牛顿第一定律看待人生
  • AMR Codec参数在SDP中的详细解析及其与AMR编解码的关系
  • 查找资料网站:
  • 云开发 | 如何获取用户输入数据,并且在云数据库中删除该条数据
  • > Invalid revision: 3.22.1-g37088a8-dirty
  • 【优选算法】(第四十五篇)