JoiOI 走廊潑水節【最小生成樹還原完全圖】
阿新 • • 發佈:2018-12-16
貪心每次取當前邊權值+1還原,每次還原條邊。
表示點所處的並查集集合中的元素個數:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define ll long long #define rel(i,x,y) for(ll i=(x);i<(y);i++) #define rep(i,x,y) for(ll i=(x);i<=(y);i++) #define red(i,x,y) for(ll i=(x);i>=(y);i--) using namespace std; const ll N=1e4+5; ll t,n,f[N],size[N]; struct node { ll x,y,z; }tr[N]; inline ll read() { ll x=0;char ch=getchar();bool f=0; while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return f?-x:x; } bool cmp(node p,node q) { return p.z<q.z; } ll find(ll x) { return f[x]==x?x:f[x]=find(f[x]); } int main() { t=read(); while(t--) { n=read(); rel(i,1,n) tr[i].x=read(),tr[i].y=read(),tr[i].z=read(); sort(tr+1,tr+n,cmp); rep(i,1,n) f[i]=i,size[i]=1; ll ans=0; rel(i,1,n) { ll fx=find(tr[i].x); ll fy=find(tr[i].y); if(fx==fy) continue; ans+=(tr[i].z+1)*(size[fx]*size[fy]-1); f[fx]=fy;size[fy]+=size[fx]; } printf("%lld\n",ans); } return 0; }