首页 > 编程知识 正文

用prim算法求下图的最小生成树,kruskal算法求最小生成树

时间:2023-05-05 14:33:22 阅读:17690 作者:3888

以前写的是Kruskal算法实现最小生成树,这次添加Prim算法

上次没有介绍最小生成树,这次一起添加吧

而且没有电路的有向图被称为树

给定无向图,你可以根据无向图来种树。 这就是图的生成树。 图的生成树可能有多个

当这个无向图为连通的赋权图时,在无向图的所有生成树中,必然存在一个边的权值和最小的生成树,被称作最小生成树

最小生成树的性质也再看一下

3358 www.Sina.com/http://www.Sina.com/kruskal和Prim算法其实是基于贪婪的,但kruskal算法必须首先对对边权重进行排序。 Prim算法每次都选择当前权重最小的边

最小生成树不能形成回路

1 .定义I=0,U=空集合,从连通图G={V,E}中的一个顶点u中选择具有最小相关权重的边(u,v ),并将该顶点添加到生成树的顶点集合u中

2 .以后,各步骤在一个顶点位于u而另一个顶点不位于u的各边缘中,从选择权值最小的边缘(u,v )开始,将该顶点追加到集合u、I中

如果i=n - 1,则算法结束。 否则,请转至步骤2并选择另一条边

基于前一种保存方法链式前向星可以写Prim算法的代码

在这里,我们使用优先队列进行了优化

最小生成树模板

ll ans; int n,m,num,cnt; int vis[maxn],dis[maxn]; int head[maxn]; typedef pair int,int pii; priority_queuepii、vector pii、greater pii q; //优先队列优化记录边权和下一个节点struct node //链前锋星{ int to; int val; 下一步; }E[maxn*2]; voidadd(intu、int v、int w ) { cnt; E[cnt].to=v; E[cnt].val=w; E[cnt].next=head[u]; head[u]=cnt; }void Prim () q.push ) make_pair ) ) 0,1 ); while (! q.empty(numn ) { int d=q.top ).first; int u=q.top ().second; q.pop (; if(vis[u] ) continue; ans =d; num; //找到边vis[u]=1标记后,我的边已经for(intI=head[u]; I; I=e [ I ].next ] if (e [ I ].valdis [ e [ I ].to ] ) /如果当前边缘权较小,则更新dis[E[i].to]=E[i].val; q.push(make_pair(e[I].val,E[i].to ) ); //对新的边界和节点进行排队} }}int main () STD :3360 IOs 33603360 sync _ with _ stdio (false ); CIN.Tie(0),cout.tie(0) ) 0; for(intI=1; imaxn; I ) dis[i]=0x3f3f3f3f; //初始化距离最大cin n m; for(intI=0; im; I ) { int u,v,w; cin u v w; add(u,v,w ); 添加(v,u,w ); //无有向图} Prim (; n==num? cout ans endl : cout 'orz' endl; 返回0; }当然,也有一些版本经过优化,但没有优先队列。 我也放在这里

int n,m,now,num,cnt,ans; int vis[maxn]、dis[maxn]、head[maxn]; //标记排列最短距离head排列structedge(//链式前锋int to; int val; 下一步; (}E[maxn]; voidadd(intu、int v、int w ) /内存映射{ cnt; E[cnt].next=head[u]; E[cnt].to=v; head[u]=cnt; E[cnt].val=w; (}int Prim ) ) {now=1; for(intI=2; i=n; I ) dis[i]=0x3f3f3f3f; //初始化距离最大为for(intI=head[1]; I!=0; I=e[I].next(/1顶点至dis[E[i].to]=min(e[I].val,dis[e[I].to] ); //寻找边权最小点while(numn-1 ) intminn=0x3f3f3f; vis[now]=1; //因为确定了第一个点,所以标记for (inti=1; i=n; I ) If (最小Ndis [ I ]! vis[I]}{minn=dis[I]; now=i; } } ans =minn; num; //边加for (inti=head [ now ]; I!=0; I=e[I].next(//当前起点为nowif ) dis[e].to ) e[I].val! vis [ e [ I ].to ] (dis [ e [ I ].to ]=e [ I ].val; } }返回Ans; (}int main ) ) {io n m; for(intI=0; im; I ) {int u,v,w; io u v w; add(u,v,w ); 添加(v,u,w ); //无有向图}printf('%dn ',Prim ) ); 返回0; }

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。