ALDS1_12_A:Minimum Spanning Tree 最小代价生成树

题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_12_A

以邻接矩阵的形式给一个有权图,求出这个图的最小代价生成树。使用prim算法的思想,复杂度只要求在n^2,不用优先队列来实现。

思路:

prim算法的思想是,对于一个有权图G,求它的MST  (Minimum Spanning Tree)

设图G(V,E)所有顶点的集合为V,MST中的顶点的集合为T。

从G中选取任意顶点r作为MST的根,将其添加到T。

循环执行下述处理,直到T=V。

在连接T内顶点与V-T内顶点的边中选取权值最小的边(pu,u),将其作为MST的边,并将u添加到T中。

我实现的方法是,先把第一个顶点放入T中,然后遍历所有节点,如果有已经处于T中的节点,就再去遍历所有节点,对于每一个在V-T中的节点,都去判断,它的权值是否是最小的,直到选取到了最小权值的边对应的节点,把那个节点放入MST中,然后循环上述过程。最后直到所有节点都已经处于T中,结束循环。

我用flag[i]来标识:顶点i是否处于T中,true表示i顶点在MST中,false表示不在;

具体代码如下:

#include <iostream>
using namespace std;
const int maxx=110;
const int infinity=(1<<30);

int A[maxx][maxx];
bool flag[maxx];	//用flag来标记这个节点是不是在MST中,true是在T里,false是在V-T里;

int main (){
		int n;
		cin>>n;
		for(int i =1;i<=n;i++){
			for(int j=1;j<=n;j++){
				int e;cin>>e;
				A[i][j]=(e==-1)?infinity:e;
			}
		}

		for(int i=0;i<maxx;i++) flag[i]=false;
		int sum=0,minv,minj;
		flag[1]=true;
		while(1){
			minv=infinity;
			minj=-1;
			for(int i=1;i<=n;i++){
				if(flag[i]==true){//找到一个在T中的顶点
					for(int j=1;j<=n;j++){
						if(A[i][j]!=-1 && A[i][j]<minv && flag[j]==false) {//找到一个在V-T中的顶点
							minv=A[i][j];//找到权值的最小值minv
							minj=j;//找到权值的最小值对应的顶点,就是下一步要加入到MST中的顶点minj
						} 
					}
				}
			}
//			cout<<minj<<endl;
			if(minv==infinity || minj==-1) break;
			flag[minj]=true;
			sum+=minv;
		}
		
		cout<<sum<<endl;
		return 0;
		
}

错点:

1.要加上结束条件 if(minv==infinity || minj==-1) break;

2.在每次循环初始要把minv和minj初始化;


猜你喜欢

转载自blog.csdn.net/qq_33982232/article/details/80643852