zoukankan      html  css  js  c++  java
  • BZOJ1778 [Usaco2010 Hol]Dotp 驱逐猪猡

    首先我们列出转移矩阵$M$,$M_{i, j} = frac {1 - frac{p} {q}} {deg[i]}$(i,j之间有边)or $M_{i, j} = 0$(i,j之间没边)

    则这个矩阵$M_{i, j}$表示的是站在某个点$i$,下一次走到$j$且没有爆炸的概率

    我们再看$M^n_{i, j}$,表示的站在某个点$i$,走$n$步以后到达$j$且没有爆炸的概率

    故$M^n$的第一列代表了$1$号点到其他所有点的概率,设为列向量$A_n$,则$A_n = M^n * B$,其中$B = (1, 0, 0, 0, ...)^T$

    设第n步到各点且爆炸了的概率的列向量为$P_n$,则$P_n = frac{p} {q} * A_n$

    故答案列向量$Ans = sum_{i = 0} ^ {+infty} P_i$

    把它展开:$Ans = frac{p} {q} * (sum_{i = 0} ^ {+infty} M^i) * B$

    由等比数列求和公式,$sum_{i = 0} ^ {+infty} M^i = frac{I} {I - M} = (I - M)^{-1}$

    故$Ans = frac{p} {q} * (I - M)^{-1} * B$,即$(I- M) * Ans = frac{p} {q} * B$

    得到一个线性方程组,我们只要高斯消元即可

     1 /**************************************************************
     2     Problem: 1778
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:200 ms
     7     Memory:2264 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cmath>
    12 #include <algorithm>
    13  
    14 using namespace std;
    15 typedef double lf;
    16 const int N = 305;
    17 const int M = N * N;
    18  
    19 inline int read();
    20  
    21 struct edge {
    22     int next, to;
    23     edge() {}
    24     edge(int _n, int _t) : next(_n), to(_t) {}
    25 } e[M];
    26  
    27 int n, m, deg[N];
    28 int first[N], tot;
    29 lf P, a[N][N], ans[N];
    30  
    31 inline void Add_Edges(int x, int y) {
    32     e[++tot] = edge(first[x], y), first[x] = tot;
    33     e[++tot] = edge(first[y], x), first[y] = tot;
    34     ++deg[x], ++deg[y];
    35 }
    36  
    37 #define y e[x].to
    38 inline void build_matrix() {
    39     int p, x;
    40     for (p = 1; p <= n; ++p) {
    41         for (x = first[p]; x; x = e[x].next)
    42             a[p][y] = -(1.0 - P) / deg[y];
    43         a[p][p] = 1;
    44     }
    45     a[1][n + 1] = P;
    46 }
    47 #undef y
    48  
    49 void gauss(int n) {
    50     int i, j, k;
    51     lf tmp;
    52     for (i = 1; i <= n; ++i) {
    53         for (k = i, j = i + 1; j <= n; ++j)
    54             if (fabs(a[j][i]) > fabs(a[k][i])) k = j;
    55         for (j = i; j <= n + 1; ++j) swap(a[i][j], a[k][j]);
    56         for (k = i + 1; k <= n; ++k)
    57             for (tmp = -a[k][i] / a[i][i], j = i; j <= n + 1; ++j)
    58                 a[k][j] += a[i][j] * tmp;
    59     }
    60     for (i = n; i; --i) {
    61         for (j = i + 1; j <= n; ++j)
    62             a[i][n + 1] -= a[i][j] * ans[j];
    63         ans[i] = a[i][n + 1] / a[i][i];
    64     }
    65 }
    66  
    67 int main() {
    68     int i, j;
    69     n = read(), m = read(), P = 1.0 * read() / read();
    70     for (i = 1; i <= m; ++i)
    71         Add_Edges(read(), read());
    72     build_matrix();
    73     gauss(n);
    74     for (i = 1; i <= n; ++i)
    75         printf("%.9lf
    ", ans[i]);
    76     return 0;
    77 }
    78  
    79 inline int read() {
    80     static int x;
    81     static char ch;
    82     x = 0, ch = getchar();
    83     while (ch < '0' || '9' < ch)
    84         ch = getchar();
    85     while ('0' <= ch && ch <= '9') {
    86         x = x * 10 + ch - '0';
    87         ch = getchar();
    88     }
    89     return x;
    90 }
    View Code
  • 相关阅读:
    原单,尾货的科普贴
    c code
    考试
    一个笔试题
    注意自己的聊天内容可能招致被拐卖儿童
    酷壳网陈皓:开发者实用学习资源汇总[转]
    性格测试
    最实用的心理调节技巧,让你的情感细胞提升一下吧!
    Makefile教程
    Extjs中的迭代
  • 原文地址:https://www.cnblogs.com/rausen/p/4523647.html
Copyright © 2011-2022 走看看