• [USACO10HOL]赶小猪


    嘟嘟嘟


    这题和某一类概率题一样,大体思路都是高斯消元解方程。


    不过关键还是状态得想明白。刚开始令(f[i])表示炸弹在点(i)爆的概率,然后发现这东西根本无法转移(或者说概率本来就是(frac{p}{q})?),于是就考虑换状态。
    一个非常好的状态是炸弹传到点(i)的概率,这样答案再乘以一个(frac{p}{q})就好了。转移也特别好办:(f[i] = sum (1 - frac{p}{q}) * frac{1}{du[v]}*f[v])
    别忘了结点1的概率要加1。
    于是这题就做完了。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<assert.h>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 305;
    const int maxe = 1e6 + 5;
    In ll read()
    {
      ll ans = 0;
      char ch = getchar(), last = ' ';
      while(!isdigit(ch)) last = ch, ch = getchar();
      while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
      if(last == '-') ans = -ans;
      return ans;
    }
    In void write(ll x)
    {
      if(x < 0) x = -x, putchar('-');
      if(x >= 10) write(x / 10);
      putchar(x % 10 + '0');
    }
    In void MYFILE()
    {
    #ifndef mrclr
      freopen(".in", "r", stdin);
      freopen(".out", "w", stdout);
    #endif
    }
    
    int n, m, p, q;
    db P;
    struct Edge
    {
      int nxt, to;
    }e[maxe];
    int head[maxn], ecnt = -1, du[maxn];
    In void addEdge(int x, int y)
    {
      ++du[x];
      e[++ecnt] = (Edge){head[x], y};
      head[x] = ecnt;
    }
    
    db f[maxn][maxn], ans[maxn];
    In void init()
    {
      f[1][n + 1] = 1;
      for(int i = 1; i <= n; ++i)
        {
          f[i][i] = 1;
          for(int j = head[i], v; ~j; j = e[j].nxt)
    	f[v = e[j].to][i] -= (1 - P) * 1.0 / du[i];
        }
    }
    In void Gauss()
    {
      for(int i = 1; i <= n; ++i)
        {
          int pos = i;
          for(int j = i + 1; j <= n; ++j)
    	if(fabs(f[j][i]) > fabs(f[pos][i])) pos = j;
          if(pos ^ i) swap(f[pos], f[i]);
          if(fabs(f[i][i]) < eps) continue;
          db tp = f[i][i];
          for(int j = i; j <= n + 1; ++j) f[i][j] /= tp;
          for(int j = i + 1; j <= n; ++j)
    	{
    	  db tp = f[j][i];
    	  for(int k = i; k <= n + 1; ++k) f[j][k] -= tp * f[i][k];
    	}
        }
      for(int i = n; i; --i)
        {
          ans[i] = f[i][n + 1];
          for(int j = i - 1; j; --j) f[j][n + 1] -= f[j][i] * ans[i];
        }
    }
    
    int main()
    {
      //MYFILE();
      Mem(head, -1);
      n = read(), m = read(), p = read(), q = read();
      P = 1.0 * p / q;
      for(int i = 1; i <= m; ++i)
        {
          int x = read(), y = read();
          addEdge(x, y), addEdge(y, x);
        }
      init(), Gauss();
      for(int i = 1; i <= n; ++i) printf("%.9lf
    ", ans[i] * P);
      return 0;
    }
    
  • 相关阅读:
    列"xx"不在表Table中
    asp.net中自定义验证控件
    ASP.NET母版与内容页相对路径的问题
    html点小图看大图最快捷的方法
    ThinkCMF的跳转303 404等页面的方法
    关于ThinkCMF自带插件上传不了图片的解决方法
    js中百分比运算,大型数据会算错
    数据库价格汇总查询的方法
    信息资源5
    操作系统概论
  • 原文地址:https://www.cnblogs.com/mrclr/p/10886756.html
Copyright © 2020-2023  润新知