感觉挺经典的一道题目。 先用 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。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <queue>
#include <sstream>
#include <iostream>
using namespace std;
#define INF 0x3fffffff
#define N 1010 struct node
{
int to,next;
}edge[*N]; int cnt,pre[N];
int n,m;
int sx,ex;
int d[N];
double dp[N][N];
int dis[N];
int next[N][N];
queue<int > que[];
int mark[N]; void add_edge(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=pre[u];
pre[u]=cnt++;
} void bfs(int s)//计算从s到其他点的下一步
{
while(que[].size()!=) que[].pop();
while(que[].size()!=) que[].pop();
int a=,b=;
memset(mark,,sizeof(mark)); for(int i=;i<=n;i++)
{
dis[i]=INF;
next[s][i]=INF;
} for(int p=pre[s];p!=-;p=edge[p].next) //找到这一个圈的点
{
int v=edge[p].to;
dis[v]=;
que[a].push(v);
next[s][v]=v;
mark[v]=;
dp[s][v]=;
}
dp[s][s]=;
next[s][s]=s;
dis[s]=;
mark[s]=;
int num=;
while(que[a].size()!=)
{
num++;
swap(a,b);
while(que[b].size()!=)
{
int cur=que[b].front();
que[b].pop();
for(int p=pre[cur];p!=-;p=edge[p].next)
{
int v=edge[p].to;
if(mark[v]==&&dis[v]<num) continue; next[s][v]=min(next[s][v],next[s][cur]); //记录从s开始出发的位置
if(mark[v]==) continue; mark[v]=; if(num==)
{
dp[s][v]=;
} dis[v]=num;
que[a].push(v);
}
}
} } void dfs(int s,int t)
{
int ts=s;
if(dp[s][t]>=) return ;
s=next[next[s][t]][t]; //先走到这一步来
double tmp=;
for(int p=pre[t];p!=-;p=edge[p].next) //在这一步中。
{
int v=edge[p].to;
dfs(s,v);
tmp += dp[ s ][v];
}
dfs(s,t);
tmp+=dp[ s ][t];
dp[ts][t]=tmp/(double)(d[t]+)+;
} int main()
{
//freopen("//home//chen//Desktop//ACM//in.text","r",stdin);
//freopen("//home//chen//Desktop//ACM//out.text","w",stdout);
scanf("%d%d",&n,&m);
scanf("%d%d",&sx,&ex);
cnt=;
memset(pre,-,sizeof(pre));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
dp[i][j]=-;
for(int i=;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
d[x]++; d[y]++;
add_edge(x,y);
add_edge(y,x);
}
for(int i=;i<=n;i++)
{
bfs(i);
}
///////////////////
dfs(sx,ex);
printf("%.3lf\n",dp[sx][ex]);
return ;
}

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. 《Javascript权威指南》学习笔记之十九--HTML5 DOM新标准---处理文档元信息和管理交互能力

    一.了解DOM 1.DOM是Document Object Model的缩写,即文档对象类型,是文档在内存中的表示形式,是一个应用程序接口,定义了文档的逻辑结构以及一套訪问和处理文档的方法. 2.HT ...

  2. 【百度地图API】怎样制作多途经点的线路导航——驾车篇

    摘要: 休假结束,酸奶小妹要从重庆驾车去北京.但是途中要去西安奶奶家拿牛奶饼干呢! 用百度地图API,能不能帮我实现这个愿望呢? ----------------------------------- ...

  3. SQL操作语句之查询及删除重复记录的方法

    delete from 表 where id not in(select min(id) from 表 group by name ) //删除重复名字的记录 删除之前请用语句 select * fr ...

  4. sass 的学习

    导入scss @import "../../sass/variables.scss"; @import "../../sass/helper.scss"; @m ...

  5. C#通过webbrowser控件与javascript交互

    1.C#里调用控件里面网页的js函数     //调用JavaScript的messageBox方法,并传入参数     object[] objects = new object[1];     o ...

  6. MapReduce编程(七) 倒排索引构建

    一.倒排索引简单介绍 倒排索引(英语:Inverted index),也常被称为反向索引.置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射. ...

  7. Atitit.隔行换色  变色 css3 结构性伪类选择器

    Atitit.隔行换色  变色 css3 结构性伪类选择器 1.1. css3隔行换色扩展阅读 1 1.2. 结构伪选择器 1 1.3. jQuery 选择器2 1.1. css3隔行换色扩展阅读 原 ...

  8. Atitit.html解析器的选型 jsoup nsoup ,java c# .net 版本

    Atitit.html解析器的选型 jsoup nsoup ,java c# .net 版本 1. 框架选型的要求1 1.1. 文档多1 1.2. 跨平台1 2. html解析器特性:1 2.1. j ...

  9. [svc]linux文件特殊权限

    这是老以前写的文章, 断断续续的可见那时候的心态还是不稳的. 生产使用: g1,g2组2个组的员工,  g2组要访问g1组/home下的文件,rx权限.  这个setfacl就有用. 方法1: 修改普 ...

  10. 代码覆盖率?coverage

    http://www.infoq.com/cn/articles/test-coverage-rate-role 代码覆盖率?coverage   http://www.cnblogs.com/cod ...