zoukankan      html  css  js  c++  java
  • hdu5723 多校第一题,longlong

    官方题解在这

    首先注意到任意两条边的边权是不一样的,由此得知最小生成树是唯一的,最小生成树既然 是唯一的,那么期望其实也就是唯一的,不存在什么最小期望。求完最小生成树之后,接下 来的问题就可以转换成在最小生成树上求任意两点之间距离的平均值,对于每条边,统计所 有的路径用到此边的次数,也就是边的两端的点数之积。那么这条边的总贡献就是次数边 权。最后得到所有边的贡献之和再除以总路径数n∗(n−1)/2n(n-1)/2n∗(n−1)/2就是答案。可以OnOnOn求出。任取一点为根dfs,对每个点iii记录其子树包含的点数(包括其自身),设点数为sum[i]sum[i]sum[i],则iii的父亲一侧的点数即为n−sum[i]n-sum[i]n−sum[i]。一边遍历一边统计就行。

    懒,longlong是个巨坑点,,,比赛时交了27次还没过(好菜啊)
    今天改个I64d就过了,,,心累

    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int M=1000007;
    const int N=100007;
    int m;
    ll n;
    struct Edge{
        int x,y;
        ll w;
        Edge(){}
        Edge(int a,int b,ll c){x=a;y=b;w=c;}
        bool operator < (const Edge e)const{return w<e.w;}
    }edges[M];
    vector<int>g[N];
    void Link(int x,int y,int e){
        g[x].push_back(e);
        g[y].push_back(e);
    }
    
    int f[N];
    int F(int x){
        return x==f[x]?x:(f[x]=F(f[x]));
    }
    
    int a[N];
    bool vis[N];
    ll SUM;
    void DFS(int x){
        vis[x]=1;
        a[x]+=1;
        for (int i=0;i<g[x].size();i++){
            Edge e=edges[g[x][i]];
            int y;if (e.x==x)y=e.y;else y=e.x;
            if (vis[y])continue;
            DFS(y);
            SUM=SUM+(ll)((ll)(n-a[y])*(ll)(a[y])*e.w);
            a[x]+=a[y];
        }
    }
    
    int main(){
        //freopen("fuck.in","r",stdin);
        int T,x,y;
        ll z;
        scanf("%d",&T);
        while (T--){
            scanf("%I64d%d",&n,&m);
            for (int i=1;i<=m;i++){
                scanf("%d%d%I64d",&x,&y,&z);
                edges[i]=Edge(x,y,z);
            }
            for (int i=1;i<=n;i++)g[i].clear();
    
            sort(edges+1,edges+m+1);       //kruskal
            for (int i=1;i<=n;i++)f[i]=i;
            int cnt=0;
            ll sum=0;
            for (int i=1;i<=m;i++){
                int x=edges[i].x;
                int y=edges[i].y;
                if (F(x)==F(y))continue;
                f[f[x]]=F(y);
                cnt++;
                Link(x,y,i);
                sum=sum+edges[i].w;
                if (cnt==n-1)break;
            }
    
            SUM = 0;
            memset(a,0,sizeof(a));
            memset(vis,0,sizeof(vis));
            DFS(1);
            double ans=2.0*SUM/(n*(n-1));
            printf("%I64d %.2lf
    ",sum,ans);
        }
        return 0;
    }
  • 相关阅读:
    POJ1239
    HDU 2829 四边形不等式优化
    返回数字二进制的最高位位数o(n)
    矩阵快速幂 模板
    HDU4718 The LCIS on the Tree(LCT)
    HDU4010 Query on The Trees(LCT)
    HDU3487 Play With Chains(Splay)
    CF444C DZY Loves Colors
    HDU4836 The Query on the Tree(树状数组&&LCA)
    HDU4831&&4832&&4834
  • 原文地址:https://www.cnblogs.com/cww97/p/12349400.html
Copyright © 2011-2022 走看看