prim生成树模板

 算法思路挺简单的,之前的prim都是用了邻接表+优先队列,但是这个最初的写法还是挺有用的。O(v^2)的复杂度,求次小生成树的时候,prim貌似是最好的选择。

krukstra不需要考虑重边的问题,但是prim要考虑。

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define res register int
const int maxn=5005;
int low[maxn];//记录每一个未遍历的点到已经在生成树上点的最短距离。 
int dis[maxn][maxn];//记录距离 
int N,M;
int vis[maxn];

int prim()
{
	int ans=0;
	for(res i=1;i<=N;i++)
	 	low[i]=dis[1][i]; 
	vis[1]=1;
	for(res i=1;i<N;i++){
		int minc=inf;
		int c=-1;
		for(res j=1;j<=N;j++){
			if(!vis[j]&&low[j]<minc){
				minc=low[j];
				c=j;
			}
		}
		if(inf==minc) return -1;
		ans+=minc;
		vis[c]=1;
		for(res j=1;j<=N;j++)
			if(!vis[j]&&low[j]>dis[c][j])
				low[j]=dis[c][j];
	}
	return ans;
}	

int main()
{
	scanf("%d%d",&N,&M);
	memset(dis,inf,sizeof(dis));
	for(res i=0;i<=N;i++)
		dis[i][i]=0;
	int a,b,c;
	for(res i=0;i<M;i++){
		scanf("%d%d%d",&a,&b,&c);
		if(c<dis[a][b])
			dis[a][b]=dis[b][a]=c;//去重边
	}
	int ans=p();
	if(-1!=ans) printf("%d",ans);
	else printf("orz");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41755258/article/details/85102184