感觉挺经典的一道题目。 先用 bfs 预处理下一步走到的位置。因为每一步走法都是固定的,所以可以用dp的方法来做。

1415: [Noi2005]聪聪和可可

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 467  Solved: 276
[Submit][Status]

Description

Input

数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数。 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号。 接下来E行,每行两个整数,第i+2行的两个整数Ai和Bi表示景点Ai和景点Bi之间有一条路。 所有的路都是无向的,即:如果能从A走到B,就可以从B走到A。 输入保证任何两个景点之间不会有多于一条路直接相连,且聪聪和可可之间必有路直接或间接的相连。

Output

输出1个实数,四舍五入保留三位小数,表示平均多少个时间单位后聪聪会把可可吃掉。

Sample Input

【输入样例1】
4 3
1 4
1 2
2 3
3 4
【输入样例2】
9 9
9 3
1 2
2 3
3 4
4 5
3 6
4 6
4 7
7 8
8 9

Sample Output

【输出样例1】
1.500
【输出样例2】
2.167

HINT

【样例说明1】
开始时,聪聪和可可分别在景点1和景点4。
第一个时刻,聪聪先走,她向更靠近可可(景点4)的景点走动,走到景点2,然后走到景点3;假定忽略走路所花时间。
可可后走,有两种可能:
第一种是走到景点3,这样聪聪和可可到达同一个景点,可可被吃掉,步数为1,概率为 。
第二种是停在景点4,不被吃掉。概率为 。
到第二个时刻,聪聪向更靠近可可(景点4)的景点走动,只需要走一步即和可可在同一景点。因此这种情况下聪聪会在两步吃掉可可。
所以平均的步数是1* +2* =1.5步。

对于所有的数据,1≤N,E≤1000。
对于50%的数据,1≤N≤50。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <algorithm>
  5. #include <math.h>
  6. #include <map>
  7. #include <queue>
  8. #include <sstream>
  9. #include <iostream>
  10. using namespace std;
  11. #define INF 0x3fffffff
  12. #define N 1010
  13.  
  14. struct node
  15. {
  16. int to,next;
  17. }edge[*N];
  18.  
  19. int cnt,pre[N];
  20. int n,m;
  21. int sx,ex;
  22. int d[N];
  23. double dp[N][N];
  24. int dis[N];
  25. int next[N][N];
  26. queue<int > que[];
  27. int mark[N];
  28.  
  29. void add_edge(int u,int v)
  30. {
  31. edge[cnt].to=v;
  32. edge[cnt].next=pre[u];
  33. pre[u]=cnt++;
  34. }
  35.  
  36. void bfs(int s)//计算从s到其他点的下一步
  37. {
  38. while(que[].size()!=) que[].pop();
  39. while(que[].size()!=) que[].pop();
  40. int a=,b=;
  41. memset(mark,,sizeof(mark));
  42.  
  43. for(int i=;i<=n;i++)
  44. {
  45. dis[i]=INF;
  46. next[s][i]=INF;
  47. }
  48.  
  49. for(int p=pre[s];p!=-;p=edge[p].next) //找到这一个圈的点
  50. {
  51. int v=edge[p].to;
  52. dis[v]=;
  53. que[a].push(v);
  54. next[s][v]=v;
  55. mark[v]=;
  56. dp[s][v]=;
  57. }
  58. dp[s][s]=;
  59. next[s][s]=s;
  60. dis[s]=;
  61. mark[s]=;
  62. int num=;
  63. while(que[a].size()!=)
  64. {
  65. num++;
  66. swap(a,b);
  67. while(que[b].size()!=)
  68. {
  69. int cur=que[b].front();
  70. que[b].pop();
  71. for(int p=pre[cur];p!=-;p=edge[p].next)
  72. {
  73. int v=edge[p].to;
  74. if(mark[v]==&&dis[v]<num) continue;
  75.  
  76. next[s][v]=min(next[s][v],next[s][cur]); //记录从s开始出发的位置
  77. if(mark[v]==) continue;
  78.  
  79. mark[v]=;
  80.  
  81. if(num==)
  82. {
  83. dp[s][v]=;
  84. }
  85.  
  86. dis[v]=num;
  87. que[a].push(v);
  88. }
  89. }
  90. }
  91.  
  92. }
  93.  
  94. void dfs(int s,int t)
  95. {
  96. int ts=s;
  97. if(dp[s][t]>=) return ;
  98. s=next[next[s][t]][t]; //先走到这一步来
  99. double tmp=;
  100. for(int p=pre[t];p!=-;p=edge[p].next) //在这一步中。
  101. {
  102. int v=edge[p].to;
  103. dfs(s,v);
  104. tmp += dp[ s ][v];
  105. }
  106. dfs(s,t);
  107. tmp+=dp[ s ][t];
  108. dp[ts][t]=tmp/(double)(d[t]+)+;
  109. }
  110.  
  111. int main()
  112. {
  113. //freopen("//home//chen//Desktop//ACM//in.text","r",stdin);
  114. //freopen("//home//chen//Desktop//ACM//out.text","w",stdout);
  115. scanf("%d%d",&n,&m);
  116. scanf("%d%d",&sx,&ex);
  117. cnt=;
  118. memset(pre,-,sizeof(pre));
  119. for(int i=;i<=n;i++)
  120. for(int j=;j<=n;j++)
  121. dp[i][j]=-;
  122. for(int i=;i<m;i++)
  123. {
  124. int x,y;
  125. scanf("%d%d",&x,&y);
  126. d[x]++; d[y]++;
  127. add_edge(x,y);
  128. add_edge(y,x);
  129. }
  130. for(int i=;i<=n;i++)
  131. {
  132. bfs(i);
  133. }
  134. ///////////////////
  135. dfs(sx,ex);
  136. printf("%.3lf\n",dp[sx][ex]);
  137. return ;
  138. }

bzoj 1415(概率dp和bfs预处理)的更多相关文章

  1. bzoj 1415 期望dp + 记忆化搜索

    思路:这个题看着感觉不能dp,其实是可以dp的,因为狼每次走两步,兔子每次走一步,每进行一轮以后,狼和兔子的距离 肯定是在接近的,没有相同的状态,dp之前预处理出来,每一步狼该往哪里走. #inclu ...

  2. BZOJ 1415: [Noi2005]聪聪和可可 [DP 概率]

    传送门 题意:小兔子乖乖~~~ 题意·真:无向图吗,聪抓可,每个时间聪先走可后走,聪一次可以走两步,朝着里可最近且点编号最小的方向:可一次只一步,等概率走向相邻的点或不走 求聪抓住可的期望时间 和游走 ...

  3. BZOJ 1415 [NOI2005]聪聪与可可 (概率DP+dfs)

    题目大意:给你一个无向联通图,节点数n<=1000.聪聪有一个机器人从C点出发向在M点的可可移动,去追赶并吃掉可可,在单位时间内,机器人会先朝离可可最近的节点移动1步,如果移动一步机器人并不能吃 ...

  4. HYSBZ 1415 - 聪聪和可可(概率DP)

    http://vjudge.net/problem/viewProblem.action?id=20613 题意:不用说了,中文题. 这个题可以用概率DP来做. 题中要求猫抓到老鼠的时间期望.分析一下 ...

  5. BZOJ 1415 聪聪和可可(期望DP)

    我们可以用n次BFS预处理出 to[][]数组,to[i][j]表示聪聪从i点到j点第一步会走哪个点. 那么对于聪聪在i点,可可在j点,聪聪先走,定义dp[i][j]表示步数期望. 那么显然有dp[i ...

  6. 【BZOJ 3811】玛里苟斯 大力观察+期望概率dp+线性基

    大力观察:I.从输出精准位数的约束来观察,一定会有猫腻,然后仔细想一想,就会发现输出的时候小数点后面不是.5就是没有 II.从最后答案小于2^63可以看出当k大于等于3的时候就可以直接搜索了 期望概率 ...

  7. BZOJ_1415_[Noi2005]聪聪和可可_概率DP+bfs

    BZOJ_1415_[Noi2005]聪聪和可可_概率DP+bfs Description Input 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2 ...

  8. 【概率DP/高斯消元】BZOJ 2337:[HNOI2011]XOR和路径

    2337: [HNOI2011]XOR和路径 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 682  Solved: 384[Submit][Stat ...

  9. BZOJ 2318: Spoj4060 game with probability Problem( 概率dp )

    概率dp... http://blog.csdn.net/Vmurder/article/details/46467899 ( from : [辗转山河弋流歌 by 空灰冰魂] ) 这个讲得很好 , ...

随机推荐

  1. C#创建COM组件供VB,PB,Delphi调用

    1  COM组件概述 COM是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术.在COM构架下,人们可以开发出各种各样的功能专一的组件,然后将它们按照需要组合起来,构成 ...

  2. Hashtable insert failed. Load factor too high. The most common cause is multiple threads writing to the Hashtable simultaneously

    暂时也没准确定位到问题 https://support.microsoft.com/zh-cn/help/2803754/hotfix-rollup-2803754-is-available-for- ...

  3. oc 阿拉伯数字转中文数字

    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; formatter.numberStyle = NSNumberFor ...

  4. 关于new与=号创建对象的区别

    (1)先定义一个名为str的对String类的对象引用变量:String str: (2)[在[栈]中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为" ...

  5. python-循环while

    while 只要…条件成立,就一直做…. for 循环会在可迭代的序列被穷尽的时候停止,while 则是在条件不成立的时候停止,因此 while 的作用概括成一句话就是:只要…条件成立,就一直做…. ...

  6. Asp.net2.0里的SessionPageStatePersister

    备注: ASP.NET 页可在处理和提供任何网页所必需的原本无状态 HTTP 请求与响应之间存储 Page 状态信息.此状态称为“视图状态”. ASP.NET 的默认持久性机制是使用 HiddenFi ...

  7. spring in action第一章小结1

    1 spring基本理念是简化java开发. 使用以下4个策略简化java开发 1) 基于POJO的轻量级和最小侵入性编程 2)通过使用DI和AOP实现松耦合 3)基于切面和惯例进行声明式编程 4)通 ...

  8. mysql操作索引的sql语句

    创建索引 一:唯一索引alter table table_name add unique index_name(column_list); 例如:alter table users_game_task ...

  9. sql中的SET NOCOUNT ON/OFF

    当 SET NOCOUNT 为 ON 时,不返回计数(表示受Transact-SQL 语句影响的行数). 当 SET NOCOUNT 为 OFF 时,返回计数(默认为OFF). 即使当 SET NOC ...

  10. PHP系统学习1

    1.php变量 2.php引用变量 $name1=&$name2; 3.全局变量 4.魔术变量__LINE__,__FILE__,__FUNCTION__,__CLASS__,__METHOD ...