【NOIP校内模拟】T2 华莱士(环套树)
生活随笔
收集整理的這篇文章主要介紹了
【NOIP校内模拟】T2 华莱士(环套树)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
其實就是要求最小的環套樹森林
我們現在只考慮如何合并 設當前邊的兩個端點是x,y
若x,y在一個聯通塊里
那這個聯通塊要么是樹 要么是環套樹
假如是個環套樹 加一條邊后必定變成兩個環 不符合要求
假如是個樹 加一條邊就變成了換套樹 符合要求
若x,y不在一個聯通塊里
假如同為環套樹 加一條邊后必定變成兩個環 不符合要求
假如同為樹 加一條邊后還是樹 符合要求
假如一棵樹 一棵環套樹 加了過后變成環套樹 符合要求
然后類似kruskal就好了
#include<bits/stdc++.h>
#define N 500005
#define int long long
using namespace std;
struct data
{int x,y,z;
}edge[2*N];
int father[N];
int n,m,tot,type[N]; //type=0 樹 type=1 環
inline bool cmp(const data &a,const data &b)
{ return a.z<b.z;
}
inline void addedge(int x,int y,int z)
{tot++;edge[tot].x=x,edge[tot].y=y,edge[tot].z=z;
}
inline int getfather(int x)
{if(father[x]==x) return x;father[x]=getfather(father[x]);return father[x];
}
main()
{cin>>n>>m;for(int i=1;i<=n;i++) father[i]=i;for(int i=1;i<=m;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);addedge(x,y,z);}sort(edge+1,edge+tot+1,cmp);int ans=0,cnt=0;for(int i=1;i<=m;i++){int fx=getfather(edge[i].x),fy=getfather(edge[i].y);if(fx==fy) //在一個聯通塊{if(type[fx]==0)//是個樹 {type[fx]=1; //他將變成環套樹 ans+=edge[i].z; ++cnt;} //環肯定是不能再加邊的 } else{if(type[fx]&&type[fy]) continue; //兩個環 father[fx]=fy;type[fy]=type[fy]|type[fx];ans+=edge[i].z; ++cnt; }}if(cnt!=n) puts("No");else cout<<ans;return 0;
}
轉載于:https://www.cnblogs.com/Patrickpwq/articles/9798702.html
總結
以上是生活随笔為你收集整理的【NOIP校内模拟】T2 华莱士(环套树)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新款奥迪Q7多少钱?
- 下一篇: 乐视手机x900怎么样 乐视手机x900