-
2020-07-09 18:45:05
有会用kruskal算法求最小生成树的吗?代价来
更多相关内容 -
JS使用Prim算法和Kruskal算法实现最小生成树
2020-12-02 10:15:32之前都是看书,大部分也是c++的实现,但是搞前端不能忘了JS啊,所以JS实现一遍这两个经典的最小生成树算法。 一、权重图和最小生成树 权重图:图的边带权重 最小生成树:在连通图的所有生成树中,所有边的权重和... -
Kruskal算法求最小生成树
2022-02-13 20:35:58求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。 由 V 中的全部 n 个顶点和 E 中 n−1 条边...给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。
求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。
给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。
由 V 中的全部 n 个顶点和 E 中 n−1 条边构成的无向连通子图被称为 G 的一棵生成树,其中边的权值之和最小的生成树被称为无向图 G 的最小生成树。
输入格式
第一行包含两个整数 n 和 m。接下来 m 行,每行包含三个整数 u,v,w,表示点 u 和点 v 之间存在一条权值为 w 的边。
输出格式
共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。数据范围
1≤n≤105,
1≤m≤2∗105,
图中涉及边的边权的绝对值均不超过 1000。输入样例:
4 5
1 2 1
1 3 2
1 4 3
2 3 2
3 4 4
输出样例:
6
题解:Kruskal算法主要思想就是先给所有权边从小到大排序,然后再判断点是否在连通块内,若不在则累加权值并将点放入连通块,连通块用并查集来存储。
代码:#include<iostream> #include<algorithm> #include<string.h> using namespace std; int n,m,res,cnt; const int N=200010; int s[N]; struct px{ int a,b,w; }p[N]; bool cmp(px a,px b){ return a.w<b.w; } int find(int a){ if(s[a]!=a)s[a]=find(s[a]); return s[a]; } int k(){ for(int i=1;i<=m;i++) { int a=p[i].a,b=p[i].b,w=p[i].w; a=find(a);b=find(b); if(a!=b) { s[a]=b; res+=w; cnt++; } } if(cnt==n-1)return res; else return -1; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int a,b,w; scanf("%d%d%d",&a,&b,&w); p[i]={a,b,w}; } sort(p+1,p+1+m,cmp); for(int i=1;i<=n;i++)s[i]=i; int t=k(); if(t==-1)printf("impossible\n"); else printf("%d\n",res); }
-
kruskal算法求最小生成树 java
2012-06-17 12:19:01kruskal算法求最小生成树 java代码 -
图论 —— Kruskal 算法求最小生成树
2022-02-06 20:42:25Kruskal 算法是一种常见并且好写的最小生成树算法,由 Kruskal 发明。该算法的基本思想是从小到大加入边。算法实现基于贪心算法。 对于一个拥有 nnn 个顶点 mmm 条边的图,其最小生成树包括 n−1n-1n−1 条边。 这个... -
Prim算法与Kruskal算法求最小生成树
2011-07-10 12:46:20Prim算法与Kruskal算法 求最小生成树 源代码 实验报告 完整 -
AcWing 859. Kruskal算法求最小生成树(Kruskal算法)
2021-06-05 21:04:01求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。 由 V 中的全部 n 个顶点和 E 中 n−1 条边...题目链接 :点击查看
题目描述 :
给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。
求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。
给定一张边带权的无向图 G=(V,E),其中 V 表示图中点的集合,E 表示图中边的集合,n=|V|,m=|E|。
由 V 中的全部 n 个顶点和 E 中 n−1 条边构成的无向连通子图被称为 G 的一棵生成树,其中边的权值之和最小的生成树被称为无向图 G 的最小生成树。
输入输出格式 :
输入
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含三个整数 u,v,w,表示点 u 和点 v 之间存在一条权值为 w 的边。输出
共一行,若存在最小生成树,则输出一个整数,表示最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。
输入输出样例 :
输入
4 5
1 2 1
1 3 2
1 4 3
2 3 2
3 4 4输出
6
题目分析 :
Kruskal算法常用于解决稀疏图的最小生成树问题。Kruskal算法也是基于贪心算法思想,不过与Prim算法不同,前者以边为主体,后者以点为主体。算法一般分为三步走 : 1. 先将图中边按权重由小到大排序。 2. 每次择取没选过的权重最小的边,判断此边加入最小生成树边集后是否构成回路,如构成回路则舍弃。 3. 选取n - 1条边使n个点相连。
以上是Kruskal算法的核心步骤。而且,我们使用结构体来存储图中边,要想将图中边按权重从小到大排序,需要在结构体内部重载 < 符号。 判断是否构成回路,我们这里要用到并查集,在Kruskal函数中,先初始化并查集,即每个点的所属集合的根节点为其本身,由于边已经排完序,我们从小到大依次选择,如果边的两个端点不再同一个集合中,则我们将两个点所属集合合并,表明将这条边加入集合。由此可见,并查集维护的是最小生成树的边集,如果两个点不属于同一个集合,说明将两个顶点之间的边加入并查集不会生成回路。我们在找每一个集合的根节点的时候,用到的是路径压缩算法。在此过程中我们用res记录最小生成树每一条边的权重,用cnt记录边的条数,每一次在判断不构成回路时,将cnt ++ ,res += w。在最后如果cnt < n -1 即选取的边数小于n - 1意味着构不成最小生成树,我们返回INF,反之则返回我们计算的权重和res。详见如下代码。
代码 :
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 1e5 + 7, INF = 0x3f3f3f3f, M = 2e5 + 7; int n, m; int p[N]; struct Edge { int v1, v2, w; bool operator < (const Edge &W) const {//重载 < 号 结构体比较按照的是边权重的大小 return w < W.w; } }edges[M]; int find(int x) { if (p[x] != x) p[x] = find(p[x]);//路径压缩 return p[x]; } int kruskal() { 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 v1 = edges[i].v1, v2 = edges[i].v2, w = edges[i].w; v1 = find(v1), v2 = find(v2); if (v1 != v2) { p[v1] = v2; res += w; cnt ++ ; } } if (cnt < n - 1) return INF; return res; } int main() { cin >> n >> m; for (int i = 0; i < m; i ++ ) { int v1, v2, w; cin >> v1 >> v2 >> w; edges[i] = {v1, v2, w}; } int t = kruskal(); if (t == INF) cout << "impossible" << endl; else cout << t << endl; return 0; }
在此给出Kruskal算法的相关模板
时间复杂度是 O(mlogm), n 表示点数,m 表示边数 int n, m; // n是点数,m是边数 int p[N]; // 并查集的父节点数组 struct Edge // 存储边 { int a, b, w; bool operator< (const Edge &W)const { return w < W.w; } }edges[M]; int find(int x) // 并查集核心操作 { if (p[x] != x) p[x] = find(p[x]); return p[x]; } int kruskal() { 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) return INF; return res; }
-
Kruskal算法 最小生成树
2018-03-08 22:05:40所以Kruskal算法的第一步是给所有的边按照从小到大的顺序排序。这一步可以直接使用库函数qsort或者sort。接下来从小到大依次考察每一条边(u,v)。 具体实现过程如下: <1> 设一个有n个顶点的连通网络为G(V,E)... -
Kruskal算法求最小生成树 Java带输入输出
2021-03-16 22:03:17Kruskal算法求最小生成树 给定一个n个点m条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。 给定一张边带权的无向图G=(V, E),其中V... -
Kruskal算法和prim算法求最小生成树学习小结(JAVA)
2019-04-12 01:38:39NULL 博文链接:https://128kj.iteye.com/blog/1705936 -
【图论】Kruskal算法求最小生成树详解
2021-08-12 15:09:22Kruskal算法求最小生成树一、算法学习前先要知道1.最小生成树概念2.数据结构:并查集二、Kruskal算法实现步骤1.把所有的边排序2.遍历所有的边三、Kruskal算法的代码实现 一、算法学习前先要知道 1.最小生成树概念 ... -
【模板】Kruskal算法求最小生成树
2020-09-14 11:30:59克鲁斯卡尔算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。 把图中的所有边按代价从小到大排序; 把图中的n个顶点看成独立的n棵树组成的... -
C语言实现克鲁斯卡尔Kruskal算法求最小生成树(附完整源码)
2021-02-22 09:52:22Kruskal算法求最小生成树Edge结构体,Graph结构体Kruskal算法求最小生成树完整源码(定义,实现,main函数测试) Edge结构体,Graph结构体 // a structure to represent a weighted edge in graph struct Edge { ... -
C++ Kruskal算法求最小生成树
2020-08-01 23:57:52最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。 ————百度百科 Kruskal算法简述 假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为: -
【模板题】Kruskal算法求最小生成树
2021-10-08 17:38:36求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。 给定一张边带权的无向图G=(V,E),其中V表示图中点的集合,E表示图中边的集合,n=|V|,m=|E|。 由V中的全部n个顶点和E中n−1条边构成的无向连通... -
用Kruskal算法求最小生成树
2021-11-05 15:56:38有n个结点,则所求的最小生成树需含有n-1条边;将图中的边,划分为两个集合,一个集合是加入了生成树的边集合(为方便称为集合A),一个是未加入生成树的边集合(为方便称为集合B)。根据贪心算法原则,每次从集合B... -
Prim算法和Kruskal算法求最小生成树
2020-10-15 12:54:45Prim算法求最小生成树 给定一个n个点m条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。 给定一张边带权的无向图G=(V, E),其中V表示... -
数据结构-kruskal算法求最小生成树_实验报告.doc
2022-05-06 19:39:46数据结构-kruskal算法求最小生成树_实验报告.doc -
算法题 Kruskal算法求最小生成树(Python)
2020-12-01 17:24:05求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible。 给定一张边带权的无向图G=(V, E),其中V表示图中点的集合,E表示图中边的集合,n=|V|,m=|E|。 由V中的全部n个顶点和E中n-1条边构成的无向... -
最小生成树(Prim,Kruskal)C++代码实现
2020-11-02 11:56:53最小生成树(Prim,Kruskal)C++代码实现 (可运行,含测试用例,有输出,注释详细) 对于一个带权连通图,生成树不同,树中各边上权值总和也不同,权值总和最小的生成树则称为图的最小生成树。 -
matlab ,kruskal算法,最小生成树
2021-03-13 08:53:42kruskal算法,最小生成树算法,内有示例,也可改成函数(在示例状态下被注释,要改成函数,取消那个注释,改下函数名或者文件名就行) -
java从文件中读取数据Kruskal算法解决最小生成树
2013-12-25 10:41:46从文件中Test类用来读取数据文件,可事先将数据输入文件中,Kruskal算法解决最小生成树 -
搜索与图论 Kruskal算法求最小生成树
2022-02-16 12:08:56Kruskal算法求最小生成树 给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G=(V,E),...