码迷,mamicode.com
首页 > 其他好文 > 详细

2016 Multi-University Training Contest 1 A

时间:2018-06-09 00:00:19      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:最小   clear   roo   names   amp   期望   ems   算法   生成树   

题意要求跑最小生成树,然后求出任意两点距离的期望。

做法是用Kruskal算法并用前向星存最小生成树,然后用dfs得出期望。

代码

#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define ll long long int

struct Edge{
    int x;
    int y;
    int wei;
}num[1010000];

struct Node {
    int to;
    int val;
    Node(int _to, int _val)
        :to(_to), val(_val) {}
};

int vis[101000];
int sum[101000];
ll res;
int n,m,k;

vector<Node>vet[101000];

int init(int n)
{
    for(int i=1;i<=n;i++)
    {
        vis[i]=i;
    }
}
int finds(int x)
{
    if(x!=vis[x])
    {
        vis[x]=finds(vis[x]);
    }
    return vis[x];
}

int cmp(Edge a,Edge b)
{
    return a.wei<b.wei;
}

void Dfs(int root, int father) {
    sum[root] = 1;
    for(int i = 0; i < vet[root].size(); i++) {
        int son = vet[root][i].to;
        int val = vet[root][i].val;
        if(son == father) continue;
        Dfs(son, root);
        sum[root] += sum[son];
        res += (ll)(sum[son]) * (ll)(n - sum[son]) * val;
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&m);
        long long int cnt=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d %d",&num[i].x,&num[i].y,&num[i].wei);
        }
        for(int i = 1; i <= n; i++) vet[i].clear();
        sort(num,num+m,cmp);
        init(n);
        for(int i=1;i<=m;i++)
        {
            int u=num[i].x;
            int v=num[i].y;
            int fu=finds(u);
            int fv=finds(v);
            if(fu!=fv)
            {
                cnt+=num[i].wei;
                vis[fu]=fv;
                vet[num[i].x].push_back(Node(num[i].y, num[i].wei));
                vet[num[i].y].push_back(Node(num[i].x, num[i].wei));
            }
        }
        memset(sum,0,sizeof(sum));
        res=0;
        Dfs(1,0);
        double exp = (double)(res) / (double)(n);
        exp = exp / (double)(n - 1) * 2.0;
        printf("%lld %.2lf\n", cnt, exp);
    }
    return 0;
}

  

2016 Multi-University Training Contest 1 A

标签:最小   clear   roo   names   amp   期望   ems   算法   生成树   

原文地址:https://www.cnblogs.com/xtuteam222/p/9157952.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!