貪心每次取當前邊權值+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;
}