题解 | #继续畅通工程#

继续畅通工程

http://www.nowcoder.com/questionTerminal/16212f7d46e44174b5505997ea998538

MST:最小生成树

  • 已修建视为成本为0

  • Kruskal:借助并查集

  • 定义边结构体,升序,依次合并不在同一连通集里的点

#include<iostream>
#include<algorithm>
using namespace std;

const int maxn=101;
int father[maxn];
int height[maxn];
void Initial(int n){
  for(int i=0;i<=n;i++){
    father[i]=i;  
    height[i]=1;
  }
}

int Find(int x){
  if(x!=father[x]){
    father[x]=Find(father[x]);
  }
  return father[x];
}

void Union(int x,int y){
  int a=Find(x);
  int b=Find(y);
  if(a==b)return;
  else if(height[a]>height[b])father[b]=a;
  else if(height[a]<height[b])father[a]=b;
  else{
    father[b]=a;
    height[a]++;
  }
}

struct Road{
  int From;
  int To;
  int Cost;
  bool operator <(Road x)const{
    return Cost<x.Cost;
  }
};

Road s[maxn*maxn];

int Kruskal(int n,int m){
  int sum=0;
  sort(s,s+m);
  Initial(n);
  for(int i=0;i<m;i++){
    Road cur=s[i];
    if(Find(cur.From)!=Find(cur.To)){
      sum+=cur.Cost;
      Union(cur.From,cur.To);
    }
  }
  return sum;
}

int main(){
  int n,m;
  while(scanf("%d",&n)!=EOF){
    m=n*(n-1)/2;
    if(n==0)break;
    for(int i=0;i<m;i++){
      int tag;
      scanf("%d%d%d%d",&s[i].From,&s[i].To,&s[i].Cost,&tag);
      if(tag==1)s[i].Cost=0;//已修建视为对应成本为0
    }
    int sum=Kruskal(n,m);
     printf("%d\n",sum);
  }
  return 0;
}

全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 15:57
小鹏汽车 java后端 22*15(固定13,2个月年终) 硕士211
点赞 评论 收藏
分享
求个付费实习岗位:这种就是吃满时代红利又没啥技术水平,只能靠压力学生彰显优越感的老登,别太在意了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务