zoukankan      html  css  js  c++  java
  • [HDOJ5723]Abandoned country(最小生成树,期望)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5723

    题意:求最小生成树,并且求这棵最小生成树上所有边走过次数的期望。

    走过次数的期望=Σ边被走过次数*边权/(n*(n-1)/2)

    求边被走过的次数,相当于关心这个边的两侧分别有多少点,走的次数就是两边的点数的乘积这个很好理解。可以从边的一侧开始dfs,找到这个边的一侧点数x,由于最小生成树是联通的,那么边的另一侧点数一定是n-x。所以这条边的贡献是(n-x)*x*w。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long LL;
     5 typedef struct Edge {
     6   int v, next;
     7   LL w;
     8 }Edge;
     9 
    10 typedef struct E {
    11   int u, v;
    12   LL w;
    13 }E;
    14 const int maxn = 200100;
    15 const int maxm = 1000100;
    16 int n, m;
    17 E e[maxm<<1];
    18 Edge edge[maxm<<1];
    19 int head[maxn], ecnt;
    20 int pre[maxn];
    21 LL ret1, ret2;
    22 
    23 int find(int x) {
    24   return x == pre[x] ? x : pre[x] = find(pre[x]);
    25 }
    26 
    27 bool unite(int x, int y) {
    28   x = find(x); y = find(y);
    29   if(x != y) {
    30     pre[x] = y;
    31     return 1;
    32   }
    33   return 0;
    34 }
    35 
    36 void init() {
    37   memset(head, -1, sizeof(head));
    38   ecnt = 0; ret1 = 0; ret2 = 0;
    39   for(int i = 1; i <= n; i++) pre[i] = i;
    40 }
    41 
    42 void adde(int u, int v, LL w) {
    43   edge[ecnt].v = v; edge[ecnt].w = w; edge[ecnt].next = head[u]; head[u] = ecnt++;
    44   edge[ecnt].v = u; edge[ecnt].w = w; edge[ecnt].next = head[v]; head[v] = ecnt++;
    45 }
    46 
    47 bool cmp(E a, E b) {
    48   return a.w < b.w;
    49 }
    50 
    51 int dfs(int u, int p) {
    52   int siz = 1;
    53   for(int i = head[u]; ~i; i=edge[i].next) {
    54     int v = edge[i].v; LL w = edge[i].w;
    55     if(p == v) continue;
    56     int pre = dfs(v, u);
    57     siz += pre;
    58     ret2 += (LL)pre * (LL)(n - pre) * w;
    59   }
    60   return siz;
    61 }
    62 
    63 int main() {
    64   //freopen("in", "r", stdin);
    65   int T, u, v;
    66   LL w;
    67   scanf("%d", &T);
    68   while(T--) {
    69     scanf("%d%d",&n,&m);
    70     init();
    71     for(int i = 0; i < m; i++) {
    72       scanf("%d%d%lld",&u,&v,&w);
    73       e[i].u = u; e[i].v = v; e[i].w = w;
    74     }
    75     sort(e, e+m, cmp);
    76     for(int i = 0; i < m; i++) {
    77       u = e[i].u; v = e[i].v; w = e[i].w;
    78       if(unite(u, v)) {
    79         ret1 += w;
    80         adde(u, v, w);
    81       }
    82     }
    83     dfs(1, -1);
    84     LL k = n * (n - 1);
    85     printf("%lld %.2lf
    ", ret1, 2.0*ret2/(double)k);
    86   }
    87   return 0;
    88 }
  • 相关阅读:
    网站前台性能优化教程
    解决Jboss打开run.bat时闪退不能启动的方法
    如何讲解自己开发的程序
    数据库调优教程汇总
    数据库调优教程(十三) MySQL数据库其他优化方法
    数据库调优教程(十二) 优化sql语句
    数据库调优教程(十一) 设计一张漂亮的表
    数据库调优教程(十) 【精华章节】解决like ’%str’ 时索引不被使用的4种方法
    数据库调优教程(九) 添加了索引但不被使用的几种常见可能
    Redis Cluster 实践
  • 原文地址:https://www.cnblogs.com/kirai/p/5978670.html
Copyright © 2011-2022 走看看