#10067. 「一本通 3.1 练习 2」构造完全图(kruskal+并查集)

  • https://loj.ac/problem/10067
  • 思路:跑一遍kruskal,并查集处理时添加新变量cnt[x]、cnt[y]存点数:cnt[i]=1,cnt[fv]+=cnt[fu];ans+=(cnt[fu]*cnt[fv]-1)*(e[i].w+1);
  • 代码:
    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    struct node{
        ll u,v,w;
    }e[100005];
    ll fa[100005],cnt[100005],cntx,cnty,w,ans;
    ll cmp(node x,node y){
        if(x.w<y.w) return 1;
        return 0;    
    };
    ll getfather(ll q){
        if(fa[q]!=q){
            fa[q]=getfather(fa[q]);
        }
        return fa[q];    
    }
    int main(){
        ll n;
        cin>>n;
        for(ll i=1;i<n;i++){
            ll x,y,z;
            cin>>x>>y>>z;
            e[i].u=x;e[i].v=y;e[i].w=z;
            ans+=e[i].w;
        }
        sort(e+1,e+n,cmp);
        for(ll i=1;i<=n;i++){
            fa[i]=i;
            cnt[i]=1;
        }
        ll fu,fv,s=0;
        for(ll i=1;i<=n;i++){
            fu=getfather(e[i].u);
            fv=getfather(e[i].v);
            if(fu!=fv){
                s++;
                ans+=(cnt[fu]*cnt[fv]-1)*(e[i].w+1);
                cnt[fv]+=cnt[fu];
                fa[fu]=fv;
            }
            if(s==n-1)break;
        }
        cout<<ans<<endl;
        return 0;
    }

     

posted @ 2019-01-24 14:54  jiansong!  阅读(663)  评论(0编辑  收藏  举报