最小生成树
Posted nent
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小生成树相关的知识,希望对你有一定的参考价值。
Kruskal
按照每条边的权值大小排序,每次加入一条最小的边(保证不会形成环,用并查集维护)直到加入了n-1条边
Kruskal适用于稀疏图
(O(m log m))
//kruskal
bool cmp(Edge x,Edge y){return x.dis<y.dis;}
void kruskal()
{
sort(e+1,e+m+1,cmp);
tot=0;
for(int i=1;i<=m;i++)
{
u=fnd(e[i].u);
v=fnd(e[i].v);
if(u==v)
continue;
tot++;
f[u]=v;
if(tot==n-1)
break;
}
}
int fnd(int x)
{
if(f[x]==x)
return x;
return f[x]=fnd(f[x]);
}
Prim
选择一个源点。加入当前权值最小的边,重复,且要求这条边的另一顶点不在树中。直至所有顶点都在树中。
Prim适用于稠密图
邻接矩阵 (O(n^2))
邻接表 (O(m log n))
//prim
void prim(int x)
{
int tot=0,now=x;
for(int i=1;i<=n;i++)
dis[i]=INF;
for(int i=head[1];i;i=e[i].next)
dis[e[i].to]=min(dis[e[i].to],e[i].dis);
while(++tot<n)
{
int mn=INF;
vis[now]=1;
for(int i=1;i<=n;i++)
if(!vis[i]&&mn>dis[i])
now=i;
for(int i=head[now];i;i=e[i].next)
if(!vis[e[i].to]&&dis[e[i].to]>e[i].dis)
dis[e[i].to]=e[i].dis;
}
}
以上是关于最小生成树的主要内容,如果未能解决你的问题,请参考以下文章