PAT8-06. 畅通工程之局部最小花费问题

mst问题

#include<queue>
#include<numeric>
#include<iostream>
using namespace std;
const int N=104;
struct road{
  int src, dst, len, ok;
  road(int a,int b,int c,int d):src(a),dst(b),len(c),ok(d){}
  bool operator<(const road&x)const{return len>x.len;}
};
priority_queue<road>ed;
   int pre[N],level[N];
void makeset(){
  iota(pre,pre+N,0);
}

int findset(int k){
  if(pre[k]!=k) pre[k]=findset(pre[k]);
  return pre[k];
}

void link(int a,int b){
  int x=findset(a),y=findset(b);
  if(level[x]>level[y])pre[y]=x;
  else{
    pre[x]=y;
    if(level[x]==level[y]) ++level[y];}
}

int main(){
  makeset();
  int n;cin>>n;
  for(int i=0,t=n*(n-1)/2;i<t;++i){
    int a,b,c,d;cin>>a>>b>>c>>d;
    ed.emplace(a,b,c,d);
    if(d)link(a,b);
  }

  int cost=0;
  while(ed.size()){
    auto x=ed.top();ed.pop();
    int a = x.src,b=x.dst;
    if(findset(a)!=findset(b)){
      link(a,b);
      cost+=x.ok?0:x.len;}
  }//while
  cout<<cost;
  return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值