2016 多校第一场 A题 Abandoned country

来源:互联网 发布:在手机淘宝上怎么赚钱 编辑:程序博客网 时间:2024/06/03 22:49

传送门
意思就是求个最小生成树,然后再求 路修建好了之后,任意两点之间的长度的期望:实际上就是求任意两点之间的平均距离。对于边X,求所有可能的路径经过此边的次数:设这条边两端的点数分别为A和B, 点A的子树的大小是size(A),设点B的子树大小是size(B),【这里所说的子树都是不经过边X的】那么这条边被经过的次数就是size(A)size(B),它对总的距离和的贡献就是sA*sB边长
sB=n(点个数)-sA,这里子树的大小自己也算进去。
然后递归,把所有的贡献都加到dis【1】除以n*(n-1)/2.

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <string>#include <vector>using namespace std;#define ll long longconst int N=1e6+10;struct node{    int u, v, w;    friend bool operator < (const node n1, const node n2){        return n1.w<n2.w;    }}a[N];struct Node{    int v, len;    Node(int _v, int _len):v(_v), len(_len){}};int fa[N];vector<Node>vec[N];int find(int x){    return fa[x]==x?x:fa[x]=find(fa[x]);}ll kruskal(int n, int m){    ll ans=0;    int tmp=0;    for(int i=1; i<=n; i++) fa[i]=i, vec[i].clear();    for(int i=0; i<m; i++)    {        if(tmp>=n-1) break;        int ui=find(a[i].u), vi=find(a[i].v);        if(ui!=vi)        {            tmp++, fa[vi]=ui, ans+=(ll)a[i].w;            vec[a[i].u].push_back(Node(a[i].v, a[i].w));            vec[a[i].v].push_back(Node(a[i].u, a[i].w));        }    }    return ans;}ll dis[N];int sum[N];int n;void dfs(int u, int p){    sum[u]=1;    for(int i=0; i<(int)vec[u].size(); i++){        int vi = vec[u][i].v;        int wi = vec[u][i].len;        if(vi==p) continue;        dfs(vi, u);        sum[u]+=sum[vi];        dis[u] += dis[vi]+((ll)sum[vi]*(n-sum[vi]))*wi;    }}int main(){    int t;    scanf("%d", &t);    while(t--){        int m, lena=0;        scanf("%d%d", &n, &m);        int ui, vi, wi;        for(int i=0; i<m; i++){            scanf("%d%d%d", &ui, &vi, &wi);            a[lena].u=ui, a[lena].v=vi, a[lena].w=wi, lena++;            //a[lena].u=vi, a[lena].v=ui, a[lena].w=wi, lena++;        }        sort(a, a+lena);        ll ans = kruskal(n, lena);        memset(dis, 0, sizeof(dis));        dfs(1, -1);        //for(int i=1;i<=n;i++)cout<<sum[i]<<endl;        ll s = (ll)n*(n-1)/2;        printf("%lld %.2lf\n", ans, dis[1]*1.0/s);    }    return 0;}
0 0
原创粉丝点击