D137 最小生成树 Kruskal 算法 U224107 联络员

D137 最小生成树 Kruskal 算法 U224107 联络员_哔哩哔哩_bilibili

 

U224107 联络员 - 洛谷  

给了两类边,一类是必选边,一类是可选边,求连通的最小费用。

思路

必选边直接加上边权,且合并集合
可选边存下来,跑最小生成树
答案 $=$ 必选边的和 $+$ 最小生成树的剩余和

相关板子:

D08【模板】最小生成树 Kruskal 算法 - 董晓 - 博客园

 

// 最小生成树 Kruskal算法 O(MlogM)
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N=2010,M=10010;
int n,m,k,tot,ans,fa[N];
struct E{int x,y,w;}e[M]; //边集

int find(int u){ //并查集的找根
  return fa[u]==u?u:fa[u]=find(fa[u]);
}
void kruskal(){
  sort(e+1,e+k+1,[&](E a,E b){return a.w<b.w;});
  for(int i=1; i<=k; i++){
    int x=find(e[i].x),y=find(e[i].y);
    if(x!=y){
      fa[x]=y;
      ans+=e[i].w;
    }
  }
  cout<<ans;
}
signed main(){
  cin>>n>>m;
  for(int i=1; i<=n; i++) fa[i]=i;
  for(int i=0,p,u,v,w; i<m; i++){
    cin>>p>>u>>v>>w;
    if(p==1){
      ans+=w;
      fa[find(u)]=find(v);
    }
    else e[++k]={u,v,w};
  }
  
  kruskal();
}

 

posted @ 2026-04-19 08:25  董晓  阅读(38)  评论(0)    收藏  举报