uva-10828 期望dp+gauss

浅浅的花香味﹌ 2022-05-09 11:08 260阅读 0赞

传送门

题意:给你一个有向图,从1号节点出发,问经过某个点的期望次数。

思路:传递闭包写错wa到哭。设 dp[i]为经过i点期望

dp[v]=dp[u1]*p1+dp[u2]*p2+….(对于第一个点应该再+1)

将每个dp看做变量,就可以构成n*n的矩阵比如样例1构成矩阵如下

-1 1 0 -1

0.5 -1 0 0

0 0.5 -1 0

用高斯消元解就可以,对于有解得dp直接输出就可以,对于无穷的,与他相关的点也无穷,也就是他传递闭包能到的点。

代码一:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define eps 1e-9
  4. const int MAXN=110;
  5. double a[MAXN][MAXN], x[MAXN];
  6. int equ, var;
  7. int n;
  8. int gauss(){
  9. int i, j, k, col, max_r;
  10. for(k=0, col=0; k<equ&&col<var; k++, col++){
  11. max_r=k;
  12. for(i=k+1; i<equ; i++)
  13. if(fabs(a[i][col])>fabs(a[max_r][col]))
  14. max_r=i;
  15. if(fabs(a[max_r][col])<eps) return 0;
  16. if(k!=max_r){
  17. for(j=col; j<var; j++)
  18. swap(a[k][j], a[max_r][j]);
  19. swap(x[k], x[max_r]);
  20. }
  21. x[k]/=a[k][col];
  22. for(j=col+1; j<var; j++) a[k][j]/=a[k][col];
  23. a[k][col]=1;
  24. for(i=0;i<equ; i++)
  25. if(i!=k){
  26. x[i]-=x[k]*a[i][col];
  27. for(j=col+1; j<var; j++) a[i][j]-=a[k][j]*a[i][col];
  28. a[i][col]=0;
  29. }
  30. }
  31. return 0;
  32. }
  33. vector<int> G[110];
  34. int dgr[110];
  35. bitset<110> inf;
  36. int mp[110][110];
  37. int main(){
  38. int cas=0;
  39. while(~scanf("%d", &n) && n){
  40. memset(a, 0, sizeof a);
  41. memset(x, 0, sizeof x);
  42. memset(mp, 0, sizeof mp);
  43. inf.reset();
  44. for(int i=0; i<n; i++)
  45. G[i].clear(), dgr[i]=0, a[i][i]=-1;
  46. int u, v;
  47. while(scanf("%d%d", &u, &v)&&(u||v)){
  48. u--; v--;
  49. G[u].push_back(v);
  50. mp[u][v]=1;
  51. dgr[u]++;
  52. }
  53. equ=n, var=n;
  54. x[0]=-1;
  55. for(int i=0; i<n; i++){
  56. for(int j=0; j<G[i].size(); j++){
  57. int v=G[i][j];
  58. a[v][i]+=1./dgr[i];
  59. }
  60. }
  61. for(int k=0; k<n; k++)
  62. for(int i=0; i<n; i++)
  63. for(int j=0; j<n; j++)
  64. if(mp[i][k] && mp[k][j]) mp[i][j]=1;
  65. gauss();
  66. for(int i=0; i<n; i++){
  67. if(fabs(x[i])>eps && fabs(a[i][i])<eps) inf[i]=1;
  68. if(inf[i])
  69. for(int j=0; j<n; j++)
  70. if(mp[i][j]) inf[j]=inf[i];
  71. }
  72. printf("Case #%d:\n", ++cas);
  73. int Q, p;
  74. scanf("%d", &Q);
  75. while(Q--){
  76. scanf("%d", &p);
  77. p--;
  78. if(inf[p])
  79. puts("infinity");
  80. else{
  81. printf("%.3lf\n", fabs(x[p]));
  82. }
  83. }
  84. }
  85. return 0;
  86. }

代码二:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define eps 1e-9
  4. const int MAXN=110;
  5. double a[MAXN][MAXN], x[MAXN];
  6. int equ, var;
  7. int n;
  8. int gauss(){
  9. int i, j, k, col, max_r;
  10. for(k=0, col=0; k<equ&&col<var; k++, col++){
  11. max_r=k;
  12. for(i=k+1; i<equ; i++)
  13. if(fabs(a[i][col])>fabs(a[max_r][col]))
  14. max_r=i;
  15. if(fabs(a[max_r][col])<eps) return 0;
  16. if(k!=max_r){
  17. for(j=col; j<var; j++)
  18. swap(a[k][j], a[max_r][j]);
  19. swap(x[k], x[max_r]);
  20. }
  21. x[k]/=a[k][col];
  22. for(j=col+1; j<var; j++) a[k][j]/=a[k][col];
  23. a[k][col]=1;
  24. for(i=0;i<equ; i++)
  25. if(i!=k){
  26. x[i]-=x[k]*a[i][col];
  27. for(j=col+1; j<var; j++) a[i][j]-=a[k][j]*a[i][col];
  28. a[i][col]=0;
  29. }
  30. }
  31. return 0;
  32. }
  33. vector<int> G[110];
  34. int dgr[110];
  35. bitset<110> inf;
  36. int main(){
  37. int cas=0;
  38. //freopen("E:/in.txt", "r", stdin);
  39. //freopen("E:/example.txt", "w", stdout);
  40. while(~scanf("%d", &n) && n){
  41. memset(a, 0, sizeof a);
  42. memset(x, 0, sizeof x);
  43. inf.reset();
  44. for(int i=0; i<n; i++)
  45. G[i].clear(), dgr[i]=0, a[i][i]=-1;
  46. int u, v;
  47. while(scanf("%d%d", &u, &v)&&(u||v)){
  48. u--; v--;
  49. G[u].push_back(v);
  50. dgr[u]++;
  51. }
  52. equ=n, var=n;
  53. x[0]=-1;
  54. for(int i=0; i<n; i++){
  55. for(int j=0; j<G[i].size(); j++){
  56. int v=G[i][j];
  57. a[v][i]+=1./dgr[i];
  58. }
  59. }
  60. gauss();
  61. for(int i=n-1; i>=0; i--){
  62. if(fabs(x[i])>eps && fabs(a[i][i])<eps) inf[i]=1;
  63. for(int j=i+1; j<n; j++) if(fabs(a[i][j])>eps && inf[j]) inf[i]=1;
  64. }
  65. printf("Case #%d:\n", ++cas);
  66. int Q, p;
  67. scanf("%d", &Q);
  68. while(Q--){
  69. scanf("%d", &p);
  70. p--;
  71. if(inf[p])
  72. puts("infinity");
  73. else{
  74. printf("%.3lf\n", fabs(x[p]));
  75. }
  76. }
  77. }
  78. return 0;
  79. }
  80. /*
  81. 3
  82. 1 3
  83. 3 2
  84. 0 0
  85. 3
  86. 1
  87. 2
  88. 3
  89. 5
  90. 1 2
  91. 3 5
  92. 2 4
  93. 3 1
  94. 4 2
  95. 2 3
  96. 4 5
  97. 0 0
  98. 5
  99. 1
  100. 2
  101. 3
  102. 4
  103. 5
  104. */

发表评论

表情:
评论列表 (有 0 条评论,260人围观)

还没有评论,来说两句吧...

相关阅读

    相关 期望DP入门

    期望DP一般步骤: 1.模拟过程,找出线性性质,作为阶段(这本质上也是线性DP) 2.涉及DP状态 原则: 体现线性性质 体现边权 根据对期望有无贡献来设计状态

    相关 期望、方差

    一、期望和方差的定义 随机变量(Random Variable) X 是一个映射,把随机试验的结果与实数建立起了一一对应的关系。而期望与方差是随机变量的两个重要的数字特征

    相关 cf期望概率专题

    cf1009E:求到第i段期望和的比较困难,但是单独求每段的期望是比较容易的,所以单独对每段求和,然后累计总和 E\[i\]=1/2\a1+1/4\a2+...+1/2^(i