对prim算法的理解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42391248/article/details/82150797

练习了两天的prim算法,谈谈对prim算法的理解。

prim算法解决的是需要求最小生成树的问题,也就是求一个连通图连通的最小权值问题。

具体操作如下:

首先你需要建图,申请一个二维数组存点,如果点过多的话,图是建不起来,二维数组申请不出来,所以点太多不适合用这个算法。i到j连通的表示:map[i][j]=map[j][i]=权值,图里当i=j时,也就是自己到自己的距离应该是0。如果两个点不连通,在图里面的权值是无穷大的。建完图后的二维数组如果看出矩阵的话,应该是斜对角线全是0(i=j),上三角和下三角关于对角线对称。

之后你需要两个数组visit[i],d[i]。visit用于判断一个点是否被判断过,d[i]用于存每个点到i点的最小的权值。

对visit初始化为1,d初始化为0。

然后就是套公式了:

//prim算法 
                for(int i=1;i<n;i++)
			d[i]=map[i][0];
		visit[0]=0;	
		int sum=0;
		for(int i=1;i<n;i++)
		{
			int minn=INF;
			int temp;
			for(int j=0;j<n;j++)
				if(minn>d[j]&&visit[j])
				{
					temp=j;
					minn=d[j];
				}					
			visit[temp]=0;
			sum+=minn;
			for(int j=0;j<n;j++)
				if(d[j]>map[j][temp]&&visit[j])
					d[j]=map[j][temp];			
		}
		
		cout<<sum<<endl;

如果需要打印生成树的边,可以设一个eg[i]数组,表示点i和eg[i]相连而且权值最小。然后找到这个点,就可以通过eg找到和其相连权值最小的边。具体操作参考一道题:POJ1751 Highways(prim打印边)

猜你喜欢

转载自blog.csdn.net/qq_42391248/article/details/82150797