acwing858 Prim算法求最小生成树(模板)

prim算法时间复杂度为o(n^2)
prim的dijkstra的不同在于点更新距离时
prim是点到集合距离,dijkstra是点到起点的距离
伪代码
res记录最小生成树的边权和,st[] 记录该点是否在集合内,初始化dist[] 记录该点到集合最近距离
st记录随机一个点到集合,(一般是1)
for 更新所有点到"集合"最短距离
for n-1次
    for 循环点,找到集合外距离"集合"最近的点t
    st记录t加入集合
    res加上t的最短距离dist[t]
    if (最短的距离dist[t]为INF )return INF 说明不是连通图,无最小生成树
    for 更新"集合"外的点到集合距离
return res
板子:
#include <bits/stdc++.h>

using namespace std;

int n,m,a,b,c;
const int N=505;
int g[N][N],dist[N];
bool st[N];//状态,是否在集合里 

int prim(){
	int res=0;
	memset(dist,0x3f,sizeof dist);
	st[1]=true;
	for(int i=2;i<=n;i++) dist[i]=min(dist[i],g[1][i]);
	for(int i=0;i<n-1;i++){
		int t=-1;
		for(int j=1;j<=n;j++){
			if(!st[j]&&(t==-1||dist[j]<dist[t])) t=j;
		}
		st[t]=true;
		res+=dist[t];
		if(dist[t]>0x3f3f3f3f/2) return dist[t];
		for(int j=1;j<=n;j++) dist[j]=min(dist[j],g[t][j]);
	}
	return res;
}
int main() {
	cin>>n>>m;
	memset(g,0x3f,sizeof g);
	while(m--){
		scanf("%d%d%d",&a,&b,&c);
		g[a][b]=g[b][a]=min(g[a][b],c);
	}
	int ans=prim();
	if(ans>0x3f3f3f3f/2) puts("impossible");
	else printf("%d\n",ans);
	return 0;
}
prim函数的稍微简便写法
int prim(){
	int res=0;
	memset(dist,0x3f,sizeof dist);
	for(int i=0;i<n;i++){//集合初始为空的情况也考虑进
		int t=-1;
		for(int j=1;j<=n;j++){
			if(!st[j]&&(t==-1||dist[j]<dist[t])) t=j;
		}
		st[t]=true;
		if(i) res+=dist[t];
		if(i&&dist[t]>0x3f3f3f3f/2) return dist[t];
		for(int j=1;j<=n;j++) dist[j]=min(dist[j],g[t][j]);
	}
	return res;
}


全部评论

相关推荐

01-24 08:13
已编辑
合肥工业大学 Java
程序员牛肉:没啥问题。标准的流水线简历,但是学历好一点,所以应该是有约面的机会的。 这段时间可以考虑把自己的两个项目彻底的理一理。争取能够讲清楚每一个功能点
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务