最小生成树

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;
	}
}
posted @ 2019-10-10 09:02  nenT  阅读(115)  评论(0)    收藏  举报