题意

题目链接

Sol

设\(f[i]\)表示从\(i\)走到\(T\)的期望步数

显然有\(f[x] = \sum_{y} \frac{f[y]}{deg[x]} + 1\)

证明可以用全期望公式。

那么我们可以把每个强联通分量里的点一起高斯消元,就做完了。

(warning:BZOJ没有C++11,但是下面的代码是正确的,至于为什么可以点题目链接。。。。)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = 1e6 + 10;
  4. inline int read() {
  5. char c = getchar(); int x = 0, f = 1;
  6. while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
  7. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  8. return x * f;
  9. }
  10. int N, M, S, T;
  11. int dfn[MAXN], low[MAXN], vis[MAXN], tot, cnt, inder[MAXN], col[MAXN], ha[MAXN];
  12. double f[201][201], deg[MAXN], ans[MAXN];
  13. stack<int> s;
  14. vector<int> v[MAXN], scc[MAXN], E[MAXN];
  15. void Pre() {
  16. for(int i = 1; i <= N; i++) {
  17. double sum = 0; f[i][i] = 1.0;
  18. for(auto &x : v[i])
  19. if(x != T) sum += 1.0 / deg[x], f[i][x] = -1.0;
  20. f[i][N + 1] = sum;
  21. }
  22. }
  23. void Gauss(int n) {
  24. for(int i = 1; i <= n; i++) {
  25. int mx = i;
  26. for(int j = i + 1; j <= n; j++) if(f[j][i] > f[mx][i]) mx = j;
  27. if(i != mx) swap(f[i], f[mx]);
  28. for(int j = 1; j <= n; j++) {
  29. if(i == j) continue;
  30. double p = f[j][i] / f[i][i];
  31. for(int k = i + 1; k <= n + 1; k++) f[j][k] -= f[i][k] * p;
  32. }
  33. }
  34. for(int i = 1; i <= n; i++) f[i][n + 1] = f[i][n + 1] / f[i][i];
  35. }
  36. void Tarjan(int x) {
  37. dfn[x] = low[x] = ++tot; s.push(x); vis[x] = 1;
  38. for(auto &to : v[x]) {
  39. if(!dfn[to]) Tarjan(to), low[x] = min(low[x], low[to]);
  40. else if(vis[to]) low[x] = min(low[x], dfn[to]);
  41. }
  42. if(low[x] == dfn[x]) {
  43. int h; cnt++;
  44. do {
  45. h = s.top(); s.pop();
  46. vis[h] = 0;
  47. scc[cnt].push_back(h);
  48. col[h] = cnt;
  49. }while(h != x);
  50. }
  51. }
  52. void solve(vector<int> &p) {
  53. memset(vis, 0, sizeof(vis));
  54. memset(f, 0, sizeof(f)); int num = p.size();
  55. for(int i = 0; i < p.size(); i++) vis[p[i]] = i + 1;
  56. for(int i = 0; i < p.size(); i++) {
  57. int x = p[i];
  58. f[i + 1][i + 1] = deg[x]; f[i + 1][num + 1] = deg[x];
  59. for(auto &to : v[x]) {
  60. if(vis[to]) f[i + 1][vis[to]] -= 1;
  61. else f[i + 1][num + 1] += ans[to];
  62. }
  63. }
  64. Gauss(num);
  65. for(int i = 0; i < p.size(); i++) ans[p[i]] = f[i + 1][num + 1];
  66. }
  67. void Topsort() {
  68. queue<int> q; q.push(col[T]);
  69. while(!q.empty()) {
  70. int p = q.front(); q.pop();
  71. for(auto &to : E[p]) if(!(--inder[to])) q.push(to);
  72. if(p != col[T])
  73. solve(scc[p]);
  74. }
  75. }
  76. int main() {
  77. N = read(); M = read(); S = read(); T = read();
  78. for(int i = 1; i <= M; i++) {
  79. int x = read(), y = read();
  80. if(x != T) v[x].push_back(y), deg[x]++;
  81. }
  82. Tarjan(S);
  83. if(!dfn[T]) {puts("INF"); return 0;}
  84. for(int i = 1; i <= N; i++) {
  85. for(auto &x : v[i])
  86. if(col[i] != col[x])
  87. inder[col[i]]++, E[col[x]].push_back(col[i]);
  88. }
  89. for(int i = 1; i <= cnt; i++) if(i != col[T] && !inder[i]) {puts("INF"); return 0;}
  90. Topsort();
  91. printf("%.3lf", ans[S]);
  92. return 0;
  93. }

BZOJ2707: [SDOI2012]走迷宫(期望 tarjan 高斯消元)的更多相关文章

  1. BZOJ.2707.[SDOI2012]走迷宫(期望 Tarjan 高斯消元)

    题目链接 一个点到达终点的期望步数 \(E_i=\sum_{(i,j)\in G}\frac{E_j+1}{out[i]}\),\(out[i]\)为点\(i\)的出度. 那么对于一个DAG可以直接在 ...

  2. bzoj 2707 [SDOI2012]走迷宫(SCC+高斯消元)

    Description Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿 ...

  3. BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元

    BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元 题意: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机 ...

  4. ZJUT 1423 地下迷宫(期望DP&高斯消元)

    地下迷宫 Time Limit:1000MS  Memory Limit:32768K Description: 由于山体滑坡,DK被困在了地下蜘蛛王国迷宫.为了抢在DH之前来到TFT,DK必须尽快走 ...

  5. BZOJ2707 [SDOI2012]走迷宫 【概率dp + tarjan + 高斯消元】

    题目 Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,Morenan非常的脑小,他只会从一个点出发随机沿着一条从该点出发的 ...

  6. BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )

    数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...

  7. 【BZOJ3143】[Hnoi2013]游走 期望DP+高斯消元

    [BZOJ3143][Hnoi2013]游走 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 ...

  8. bzoj3143 游走 期望dp+高斯消元

    题目传送门 题意: 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得 ...

  9. BZOJ2707 : [SDOI2012]走迷宫

    首先求出SCC缩点,E[T]=0,按拓扑序计算 对于无边连出的块,如果不是T所在块,则称该块是死路块 对于一个块,如果其中的点连出的边是死路块,则它也是死路块 否则对于每块进行高斯消元求出期望 如果S ...

随机推荐

  1. C#6.0语言规范(十七) 特性

    许多C#语言使程序员能够指定有关程序中定义的实体的声明性信息.例如,在一个类中的方法的可访问性由与装饰它指定method_modifier小号public,protected,internal,和pr ...

  2. 修改oracle默认监听端口

    修改oracle默认监听端口 oracle端口修改 主要是修改两个文件和修改oracle参数local_listener 1 查看当前监听状态 [oracle@test ~]$ lsnrctl sta ...

  3. B2C电商项目

    经历四个月的自学. 结合所学的知识(HTML,CSS,javascript,jQuery,Mysql,Redis,Django,celery,fastDfs,haystack,whoosh,uWSGI ...

  4. 原生JS实现AJAX、JSONP及DOM加载完成事件,并提供对应方法

    JS原生AJAX ajax:一种请求数据的方式,不需要刷新整个页面: ajax的技术核心是 XMLHttpRequest 对象: ajax 请求过程:创建 XMLHttpRequest 对象.连接服务 ...

  5. 【并发】3、LockSupport阻塞与唤醒,相较与wait和notify

    我们可以使用wait和notify分别对象线程进行阻塞或者唤醒,但是我们也可以使用LockSupport实现一样的功能,并且在实际使用的时候,个人感觉LockSupport会更加顺手 范例1,wait ...

  6. 服务器返回的http状态码

    状态码 响应类别 原因短语 1XX 信息性状态码(Informational) 服务器正在处理请求 2XX 成功状态码(Success) 请求已正常处理完毕 3XX 重定向状态码(Redirectio ...

  7. 判断一个类是否为另一个类的实例 instanceof关键字和isAssignableFrom方法的区别

    Which of the following is better? a instanceof B or B.class.isAssignableFrom(a.getClass()) The only ...

  8. Linux下ps -ef 和 ps aux的区别

    Linux下显示系统进程的命令ps,最常用的有ps -ef 和ps aux.这两个到底有什么区别呢?两者没太大差别,讨论这个问题,要追溯到Unix系统中的两种风格,System V风格和BSD 风格, ...

  9. VS2015 WPF Prism Xaml Designer error

    Ref: http://wiki.tk2kpdn.com/build-error-prism5-interactionrequesttrigger-with-vs2015/ gacutil -i &q ...

  10. C#简单操作MongoDB

    一 安装MongoDB 官网按需下载, 安装, 一步到位. 二 VS创建新项目 创建一个.netcore console项目, 然后nuget安装驱动MongoDB.Driver 三 建立连接 在Pr ...