最小生成树问题(下)

克鲁斯卡尔算法

简述

这种算法是求最短的合法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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值