zoukankan      html  css  js  c++  java
  • 游走 BZOJ 3143

    游走

    【问题描述】

     

    【输入格式】

     

    【输出格式】

     

    【样例输入】

    3 3

    2 3

    1 2

    1 3

    【样例输出】

    3.333

    【样例说明】

     


    题解:

    题意是给一个简单无向连通图,给每条边赋上权值,使期望值最小

    贪心让被走到概率大的边的权值小,就可得到最小的期望值

    设每个点被走到的概率为p, 出度为d

    那么p[i] = Σ p[j] / d[j] (i,j 之间有连边) (从 j 出发选到 i 与 j 连边的概率为 1 / d[j])

    移项得 Σ p[j] / d[j] - p[i] = 0

    对于每个点我们都可以列出一个含有n个未知数的方程

    特别地,p[1]概率需要加一 , p[n] = 1 (起点为1,终点为n)

    那么就可以进行高斯消元啦

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cstdio>
     6 #include<cmath>
     7 using namespace std;
     8 inline void Scan(int &x)
     9 {
    10     char c;
    11     while((c = getchar()) < '0' || c > '9');
    12     x = c - '0';
    13     while((c = getchar()) >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0';
    14 }
    15 double eps = 1e-6;
    16 int n, m;
    17 double c[523];
    18 double a[523][523];
    19 int x[523], y[523];
    20 int de[523];
    21 double ans;
    22 inline void Solve()
    23 {
    24     int now;
    25     double t;
    26     for(int i = 1; i <= n; ++i)
    27     {
    28         now = i;
    29         while(fabs(a[i][now]) <= eps && now <= n) ++now;
    30         if(now > n) continue;
    31         for(int j = 1; j <= n + 1; ++j) swap(a[i][j], a[now][j]);
    32         t = a[i][i];
    33         for(int j = 1; j <= n + 1; ++j) a[i][j] /= t;
    34         for(int j = 1; j <= n; ++j)
    35             if(i != j)
    36             {
    37                 t = a[j][i];
    38                 for(int k = 1; k <= n + 1; ++k)
    39                     a[j][k] -= a[i][k] * t;
    40             }
    41     }
    42 }
    43 int main()
    44 {
    45     Scan(n), Scan(m);
    46     for(int i = 1; i <= m; ++i)
    47     {
    48         Scan(x[i]), Scan(y[i]);
    49         ++de[x[i]], ++de[y[i]];
    50     }
    51     for(int i = 1; i <= m; ++i)
    52     {
    53         a[x[i]][y[i]] += 1.0 / (double) de[y[i]];
    54         a[y[i]][x[i]] += 1.0 / (double) de[x[i]];
    55     }
    56     for(int i = 1; i <= n + 1; ++i) a[n][i] = 0;
    57     for(int i = 1; i <= n; ++i) a[i][i] = -1;
    58     a[1][n + 1] = -1;
    59     Solve();
    60     for(int i = 1; i <= m; ++i)
    61         c[i] = a[x[i]][n + 1] / (double) de[x[i]] + a[y[i]][n + 1] / (double) de[y[i]];
    62     sort(c + 1, c + 1 + m);
    63     for(int i = 1; i <= m; ++i)
    64         ans += c[i] * (m - i + 1);
    65     printf("%.3lf", ans);
    66 }
  • 相关阅读:
    如何隐藏DLL中,导出函数的名称?
    排序算法之0-1、0-1-2排序
    在Vista以上版本运行WTL程序,有时候会提示“这个程序可能安装补正确...”的错误
    编码格式(未完待续......)
    WinDbg分析DUMP文件
    自己捣鼓了一个12306抢票软件,欢迎大家使用,并讨论改进方法!
    Cocos2D-X扫盲之坐标系、锚点
    Spring核心组件剖析
    走进Java中的持有对象(容器类)【二】Collection
    走进JVM【二】理解JVM内存区域
  • 原文地址:https://www.cnblogs.com/lytccc/p/6241057.html
Copyright © 2011-2022 走看看