LOJ10067 构造完全图
最小生成树
每次找到最小的边,将边两端的块合并
(我之前想的是什么鬼)
#include<cstdio> #include<algorithm> using namespace std; struct data{int f,t,d;}a[100002]; int n,fa[100002],siz[100002]; long long ans; inline bool cmp(const data &A,const data &B) {return A.d<B.d;} inline int find(int x) {return x==fa[x] ? x:fa[x]=find(fa[x]);} int main(){ scanf("%d",&n); for(int i=1;i<n;++i){ scanf("%d%d%d",&a[i].f,&a[i].t,&a[i].d); ans+=a[i].d; fa[i]=i; siz[i]=1; }fa[n]=n; siz[n]=1; sort(a+1,a+n,cmp); //按边排序 for(int i=1;i<n;++i){ int r1=find(a[i].f),r2=find(a[i].t); ans+=1LL*(siz[r1]*siz[r2]-1)*(a[i].d+1); //每2个不同块的点都连起来 fa[r2]=r1; siz[r1]+=siz[r2]; //合并 } printf("%lld",ans); return 0; }