D137 最小生成树 Kruskal 算法 U224107 联络员
D137 最小生成树 Kruskal 算法 U224107 联络员_哔哩哔哩_bilibili
给了两类边,一类是必选边,一类是可选边,求连通的最小费用。
思路
必选边直接加上边权,且合并集合
可选边存下来,跑最小生成树
答案 $=$ 必选边的和 $+$ 最小生成树的剩余和
相关板子:
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(); }
浙公网安备 33010602011771号