Codeforces Round #535 (Div. 3) F
阿新 • • 發佈:2019-01-28
define 題意 http 答案 def nod hid efi eve
F. MST Unification
題目傳送門
題意:
給你n個頂點,m條邊;保證沒有重邊,其中存在多個MST(最小生成樹),
你可以修改一些邊的權值,讓其中有且僅有一個最小生成樹,求最少操作的邊數。
思路:
最小生成樹算法的加工,我們從kruskal算法入手,kruskal就是先對邊排序,
然後遍歷邊不斷加入一些合格邊來完善最小生成樹
那麽在這個過程中,如果邊的權值一樣的話,就會產生多種MST,但是這裏
不能僅僅只是累計相同權值的邊數,因為與合格邊相同權值的邊可能可以選擇
多條。
所以我們可以將所有符合的邊累加起來,然後減去(n-1)就是與合格邊沖突的邊
,也就是答案了
#include<bits/stdc++.h> using namespace std; #define N 200005 int n,m; struct node { int u,v,w; bool operator <(const node &p) const{ return w<p.w; } }edge[N]; int fa[N]; int Find(int x) { if(x==fa[x]) return x; else return fa[x]=Find(fa[x]); }View Codeint main() { while(~scanf("%d %d",&n,&m)) { for(int i=0;i<m;i++) scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w); for(int i=1;i<=n;i++) fa[i]=i; sort(edge,edge+m); int ans=0; int L=0; for(int i=0;i<m;i++) {int u=edge[i].u,v=edge[i].v; u=Find(u),v=Find(v); if(u!=v) ans++; if(i+1<m && edge[i].w!=edge[i+1].w) { for(int j=L;j<=i;j++) { int u=edge[j].u,v=edge[j].v; u=Find(u),v=Find(v); if(u!=v) fa[u]=v; } L=i+1; } } printf("%d\n",ans-(n-1)); } }
Codeforces Round #535 (Div. 3) F