最小生成树——Prim&&Kruskal

大话数据结构-普里姆算法(Prim)和克鲁斯卡尔算法(Kruskal) 最小生成树的定义,普里姆算法(Prim)和克鲁斯卡尔(Kruskal),以及各种存储结构下的最小生成树的代码实现。 阅读详情

这几天做的几套模拟题都要用最小生成树搞~忘得都差不多的我特地来打两个板子。

首先,二者均采用贪心策略。

算法过程:大概是不断从未知集合往已知集合加元素。

感性理解:对于一颗树中的节点(u,v),如果二者间的边权w1小于u->v路径中的边权w2,显然断开w2连接w1更优,这时我们证明了对于max(u->v)<w(u,v);而如果我们采用贪心策略每次选中连接未知集合和已知集合最小边,显然得到的u->v路径上的边都是最小的,即不存在更优解,那么贪心得到的解即是最优解。

#include<bits/stdc++.h>
using namespace std;
#define Inc(i,L,r) for(register int i=(L);i<=(r);++i)
const int N = 1010,Maxe=N*(N-1)/2;
struct Edge{
	int cnt,h[N],w[Maxe],to[Maxe],next[Maxe];
	inline void add(int x,int y,int z){
		next[++cnt]=h[x];to[cnt]=y;w[cnt]=z;h[x]=cnt;
	}
}e;
struct Node{
	int idx,dist;
	bool operator <(const Node&A)const {
		return A.dist<dist;
	}
};
struct MST{
	int n,m;
	bool vst[N];
	inline void init(){
		scanf("%d%d",&n,&m);
		Inc(i,1,m){
			int x,y,z;scanf("%d%d%d",&x,&y,&z);
			e.add(x,y,z),e.add(y,x,z);
		}
	}
	priority_queue<Node>Q;
	inline void Prim(){
		Q.push((Node){1,0});
		while(!Q.empty()){
			int x=Q.top().idx,dist=Q.top().dist;Q.pop();
			if(vst[x])continue;
			vst[x]=1;
			for(int p=e.h[x];p;p=e.next[p])
				if(!vst[e.to[p]])Q.push((Node){e.to[p],e.w[p]});
		}
	}
};
#include<bits/stdc++.h>
using namespace std;
#define Inc(i,L,r) for(register int i=(L);i<=(r);++i)
const int N = 510,M = 3e5+10;
struct edge{
	int u,v,w;
	bool operator <(const edge&A)const {
		return A.w>w;
	}
};
struct MST{
	int n,m,fa[N];
	edge e[M];
	inline void init(){//n个点,m条边 
		scanf("%d%d",&n,&m);
		for(int i=1;i<=m;i++){
			int x,y,z;scanf("%d%d%d",&x,&y,&z);
			e[i]=(edge){x,y,z};
		}
	}
	inline int getfa(int u){
		return u!=fa[u]?fa[u]=getfa(fa[u]):u;
	}
	inline void Kruskal(){
		sort(e+1,e+m+1);
		for(int i=1;i<=n;i++)fa[i]=i;
		for(int i=1;i<=m;i++){
			int nd1=e[i].u,nd2=e[i].v;
			int f1=getfa(nd1),f2=getfa(nd2);
			if(f1==f2)continue;
			fa[f2]=f1;
		}
	}
};

比较Prim和Kruskal算法,前者是针对点,后者是对于边。

那么,prim显然更加适合稠密图,kruskal则对于稀疏图更优。

顺带一提:我的prim写法为了和较大数据规模搞,用的优先队列+邻接表,于是时间复杂度(n+m)logm,实际上,可以用邻接矩阵存储保证严格n^2。

数据结构与算法 —— 最小生成树Prim算法和Kruskal算法详细图解以及python实现 上一章我们整理了最短路径中的Dijkstra算法。现在我们整理最小生成树中Prim算法(普里姆算法)和Kruskal算法(克鲁斯卡尔算法)。最小生成树也是图论中常见问题,其指的是在一个图中找到一个连通子图,使得所有节点都能够互相到达,且总权值最小。最小生成树的例子在生活中也很常见,比如城市的公交线路系统需要规划如何走完一趟路径和是最短的,或者快递公司如何给不同住址的客户送货才能是最短的路径。2. Prim算法(普里姆算法)2.1 Prim算法历史。 阅读详情

相关推荐

最小生成树(Prim、Kruskal)算法,秒懂!

前言 在数据结构与算法的图论中,(生成)最小生成树算法是一种常用并且和生活贴切比较近的一种算法。但是可能很多人对概念不是很清楚,什么是最小生成树? 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。 通俗易懂的讲就是最小生成树包含原图的所有节点而只用最少的边和最小的权值距离。因为n个节点最少需要n-1个边联通,而距离就需要采取某种策略选择恰当的边。 学习最

bigsai 4万+

Kruskal算法动态演示(2)

Kruskal算法是数据结构中求图的最小生成树的一个经典算法,也是数据结构课程设计的重点,这里把自己的一点工作分享给大家交流参考,希望能够造福后来者

45个经典的算法Flash动画演示

算法入门资源,便于快速掌握和复习。学的久了忘记的也可以用来回顾下……

图详解第三篇:最小生成树(Kruskal算法+Prim算法)

最小生成树:Kruskal算法+Prim算法

m0_70980326的博客 2万+

第二十一章 Prim算法与Kruskal算法(通俗证明与详细讲解)

用通俗的证明和详细的代码解析帮助你理解并掌握最小生成树问题中的两个算法:prim算法和kruskal算法。

Turing_Sheep的博客 4098

【图解】Prim和Kruskal算法的区别

【贪心】Prim和Kruskal算法的区别 Kruskal算法和Prim算法的优劣 Kruskal算法,相较于Prim算法是基于点的操作,Kruskal算法是基于边的操作,思想也比Prim简单,更容易理解 Prim算法是采用从点方面考虑来构建MST的一种算法,Prim 算法在稠密图中比Kruskal优。 示例 Prim算法 从源点出发,把源点所有的边加入一个集合(称为待选边集合E{}) 图1 从E{}中选出最短边,连接并移除,并将该点的所有的边加入E{} 图2 ...

weixin_61087354的博客 1万+

最小生成树Prim&&Kruskal算法

1.Prim算法 以下的两张图借用大佬勿在浮砂筑高台 这个算法和最短路中的Dijkstra很类似,实际上就是贪心的思想,初始化dis[1]=0,先遍历每一个点,选择该点过后标记为已经找过,然后更新到每一个点的最短路径,选择已经更新过的最短路径。 洛谷P3366最小生成树模板题 https://www.luogu.org/problemnew/show/P3366 **注意:**可能两个结点之间可...

FILWY_M 160

最小生成树(prim&&kruskal)

下面介绍两种求最小生成树算法 1.Kruskal算法 此算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。 1. 把图中的所有边按代价从小到大排序; 2. 把图中的n个顶点看成独立的n棵树组成的森林; 3. 按权值从小到大选择边,所选的边连接的两个顶点ui,vi。ui,vi,应属于两颗不同的树,则成为最小生成树的一条边,

Mi-Queen 225

图--最小生成树Prim&&Kruskal

如果无向连通图 G 的一个子图是一棵包含图 G 所有顶点的树,则称该子图为 G 的生成树。一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。如果生成树中再添加一条边,则必定成环。图的生成树不唯一。从不同的顶点出发进行遍历,可以得到不同的生成树。最小生成树:在无向连通图的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。为了找到无向图的最小生成树,常用的算法有【Prim算法】和【Kruskal算法】。

qq_66478305的博客 655

算法exp3_Prim&&Kruskal最小生成树

算法实验3 代码链接

Xixoqw的博客 538

最小生成树模板&&总结--Prim&&Kruskal

一.最小生成树:连通N个点的边权值总和最小的树。 二.时间复杂度 Prim算法:时间复杂度O(|V|2+|E|),O(|E|log|V|) Kruskal算法:时间复杂度O(|E|log|E|) 算法的选择: 从图的稀疏程度考虑(稠密图Prim,稀疏图Kruskal或Prim + Heap) 三.具体算法   1.Prim算法:(1) 任意选定一点s,设集合S={s}        ...

壹零柒 274

最小生成树Prim&&Kruskal 算法 详细笔记

  POJ 1258 Agri-Nethttp://poj.org/problem?id=1258; 两种算法 Prim Kruskal. 先说Prim 初始化  权值,随便一个顶点做起点,为0 其它的为最大值。 1.     找到权值最小的顶点,且没有加入集合。2.     把顶点权值加到结果,把定点加入集合。3.     暴力枚举 顶点连接的所有的边,更新所有能够连接上顶点的权值。4.    ...

尘的博客 238

图论--最小生成树总结(Prim&&Kruskal

今天才写了prim的堆优化,发现kruskal居然比prim跑得快。。。回归正题: 以下是我个人对最小生成树各种算法的理解,以及我的代码。 以下我将点数称为n,边数称为m;Prim 算法过程(来自百度百科): 1. 输入:一个加权连通图,其中顶点集合为V,边集合为E; 2. 初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空; 3. 重复下列操作

玫葵之蝶 498

最小生成树之普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法

作者:STzen 链接:https://www.jianshu.com/p/683ffde4f3a3 来源:简书 最小生成树 列子引入 如图假设v0到v8表示9个村庄,现在需要在这9个村庄假设通信网络。村庄之间的数字代表村庄之间的直线距离,求用最小成本完成这9个村庄的通信网络建设。 分析 这幅图是一个带权值的图,即网结构。 所谓最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使...

糖长老莫小贝的博客 2万+

Prim算法、Kruskal算法

文章目录Prim算法Kruskal算法 主要内容: Prim算法 最小生成树对应的问题一般都是无向图,最小生成树所构成的图总边权之和最小,但不能是环,否则不能称之为"最小"。 Prim算法是求解最小生成树的算法之一,适用于稠密图,Prim算法和Dijkstra算法步骤很相似,不同的是Dijkstra需要更新所有邻居到起点的距离,也就是"松弛操作",但Prim不需要,只需要把距离集合最近的点加...

ker的博客 5410

最小生成树——Prim算法与Kruskal算法

讲解图论中构造最小生成树的Prim算法思想,并通过C语言实现算法。

仅以此博客记录日常学习工作中所思所得,水平有限,难登大雅,万望海涵。 1778
上一篇: 训练场(倍增练习)
下一篇: 分组行动
DancingZ
博客等级 码龄9年 10粉丝 137原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值