简述
这种算法是求最短的合法n-1条边,用到了并查集,来避免环的产生。
代码及注释
#include<iostream>
#include<algorithm>
#define M 0x3f3f3f3f
using namespace std;
struct Node{//创建一个结构体数组 存点的位置和权值
int x,y,value;
Node(){value=M;}//将所有点权值设为无穷大 表示到不了
};
int n,m,v[101]={0},f[101];//一个标记是否访问 一个家族谱数组
int ans=0;
Node q[1010];
int cmp(Node x,Node y){
return x.value<y.value;
}
void init(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int a;//中间量
cin>>a;//输入i到j的权值大小
if(j<i){//矩阵只输入下半个直角三角形(前提无向图)
if(a!=0){//如果不能到就不改变正无穷的大小
q[i*j].x=i;q[i*j].y=j;q[i*j].value=a;//存入对应位置
}
}
}
}
sort(q+1,q+1+n*n,cmp);//根据权值大小排序 注意范围是1-n*n
/*cin>>m;
for(int i=1;i<=m;i++){
cin>>q[i].x>>q[i].y>>q[i].value;
}//对应点点边输入格式
sort(q+1,q+1+m,cmp);*/
for(int i=1;i<=n;i++){f[i]=i;}
return;
}
int getfa(int num){
if(f[num]==num){return num;}
f[num]=getfa(f[num]);
return f[num];
}
void kru(){
int i=0,h=0,fx,fy,x,y; //h是指针 负责提出q里面的数
while(i<n-1){//设置i来表示加进答案的边数
h++;
x=q[h].x;y=q[h].y;
fx=getfa(x);fy=getfa(y);
if(fx!=fy){//不是一家
f[fy]=fx;//建立联系
v[x]=1;v[y]=1;//标记访问
ans+=q[h].value;//答案加权
i++;//边数++
}
}
return;
}
int main(){
init();
kru();
cout<<ans<<"\n";
return 0;
}