题目链接: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初始化;