CodeForces - 123E Maze
http://codeforces.com/problemset/problem/123/E
题目翻译:(翻译来自: http://www.cogs.pw/cogs/problem/problem.php?pid=1734)
一个迷宫是一棵树(即一张无向图,其中任意两点之间仅有一条路径)。迷宫的起点和终点都按照某种概率随机选取。人们会在迷宫中用深度优先搜索的方法搜寻终点。如果有许多条可能的路径,会等概率地选取一条。考虑如下伪代码:
DFS(x)
if x == exit vertex then
finish search
flag[x] <- TRUE
random shuffle the vertices' order in V(x) // here all permutations have equal probability to be chosen
for i <- 1 to length[V] do
if flag[V[i]] = FALSE then
count++;
DFS(y);
count++;
V(x)是和x相邻的顶点列表。最初flag数组的值均为false。第一次DFS的参数是迷宫的入口节点。当搜索终止,变量count的值就是在迷宫中走的步数。
你的任务是计算在迷宫中从入口到出口,所走的期望步数。
题解:
首先一看知道题就知道应该去求每个点对答案的贡献
现在考虑如何求出这个贡献。
我们发现如果我们单独枚举一个点,那么这个点的情况一共有三种:
1.必定被经过
2.必定不被经过
3.不一定被经过
这样就不好统计了,所以我们先转换一下思维
怎样才能准确的找出经过的路径? 最直接的方法就是暴力枚举所有的起点和终点
这样路径就唯一确定了,直接在这个图中求一边期望,然后加权求和
可是 n <= 10^5,暴力肯定无法通过,但是有值得我们借鉴的思维
枚举端点
我们可以枚举终点,这样情况就分成了。。。还是三种:
1.起点就是终点,贡献为0,该情况可以忽略
2.起点在以终点为根的子树中
3.起点不在以终点为根的子树中
对于第二种情况,我们可以直接计算贡献,即(子树的节点数目*子树中有一个点作为入口的概率)
对于第三种情况,我们也可以直接计算的,即(除去子树后树的节点数目*除去子树后树中存在入口的概率)
为什么能这么计算呢?
我们考虑一下,如果根的某一个儿子是入口,那么贡献应为0.5*siz[v]*2
我们发现,如果一条路径经过n个点两次后到达出口,那么对答案的贡献即为(n<<1)
我们可以这么想,把题目中给的伪代码改动一下,那么每次到达一个点++count,退出一个点++count
最后再--count,这样就是这条路径对答案的贡献。
所以,我们直接刨去到达终点时对答案做出的贡献,那么就可以得到刚才的式子了
我们考虑进行推广,发现所有的点都满足这个式子
所以我们可以直接对若干个点直接加和,那么就是上面提到的计算方式了
O(n)
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=*x+ch-'',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = ;
struct Edge{
int to,next;
}G[maxn<<];
int head[maxn],cnt;
void add(int u,int v){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
}
int siz[maxn],ex[maxn],en[maxn];
int fa[maxn],n;
ll sn=,sx=,ans = ;
#define v G[i].to
void dfs(int u){
siz[u] = ;
for(int i = head[u];i;i=G[i].next){
if(v == fa[u]) continue;
fa[v] = u;
dfs(v);
siz[u] += siz[v];
en[u] += en[v];
ans += 1LL*ex[u]*en[v]*siz[v];
}ans += 1LL*ex[u]*(sn - en[u])*(n - siz[u]);
}
#undef v
int main(){
read(n);
for(int i=,u,v;i<n;++i){
read(u);read(v);
add(u,v);add(v,u);
}
for(int i=;i<=n;++i){
read(en[i]),read(ex[i]);
sn += en[i];sx += ex[i];
}dfs();
printf("%.60lf\n",(double)ans/(1.0*sn*sx) );
getchar();getchar();
return ;
}
CodeForces - 123E Maze的更多相关文章
- Codeforces 123E Maze(树形DP+期望)
[题目链接] http://codeforces.com/problemset/problem/123/E [题目大意] 给出一棵,给出从每个点出发的概率和以每个点为终点的概率,求出每次按照dfs序从 ...
- Codeforces 377A - Maze
A. Maze 题目链接:http://codeforces.com/contest/377/problem/A time limit per test 2 seconds memory limit ...
- CodeForces - 377A Maze BFS逆思维
Maze Pavel loves grid mazes. A grid maze is an n × m rectangle maze where each cell is either empty, ...
- CodeForces 378C Maze (DFS)
题目链接 题意:给一个由“.”组成的联通区域,求再添加k个‘#'以后还是联通区域的方案. 分析:做题的时候犯二了,用DFS,一直搜到边缘,然后从边缘依次往回 回溯,回溯的过程中填充’#‘ 一直填充k个 ...
- Codeforces 404E: Maze 1D(二分)
题意:指令“R”机器人会向右走一步,“L”是向左.起初机器人在0位置,可以在除了0以外的任何位置放障碍,如果机器人的指令将使它走到障碍上,那这一步他会保持不动.要求让机器人最终结束的那一步一定只走过一 ...
- Codeforces Round #222 (Div. 1) A. Maze dfs
A. Maze 题目连接: http://codeforces.com/contest/377/problem/A Description Pavel loves grid mazes. A grid ...
- Codeforces Round #222 (Div. 1) Maze —— dfs(连通块)
题目链接:http://codeforces.com/problemset/problem/377/A 题解: 有tot个空格(输入时统计),把其中k个空格变为wall,问怎么变才能使得剩下的空格依然 ...
- [CodeForces - 197D] D - Infinite Maze
D - Infinite Maze We've got a rectangular n × m-cell maze. Each cell is either passable, or is a wal ...
- Codeforces 197D - Infinite Maze
197D - Infinite Maze 思路:bfs,如果一个点被搜到第二次,那么就是符合要求的. 用vis[i][j].x,vis[i][j].y表示i,j(i,j是取模过后的值)这个点第一次被搜 ...
随机推荐
- iBatis2 SqlMap中经常使用sql语句
本来我也不喜欢iBatis,那是由于我当时还不怎么会用它,如今我想说,iBatis是个好东西,不信你试试看.以下是我在项目实践中对iBatis的一个小总结.希望帮助众多在疲于iBatis编码而无暇思考 ...
- LinkedList 基本示例及源码解析
目录 一.JavaDoc 简介 二.LinkedList 继承接口和实现类介绍 三.LinkedList 基本方法介绍 四.LinkedList 基本方法使用 五.LinkedList 内部结构以及基 ...
- eclipse不能添加tomcat
有时候原来能新建server,删掉后就不能新建了 1.退出eclipse 2.到[工程目录下 workspace ]/.metadata/.plugins/org.eclipse.core.runti ...
- 非标准USBasp下载线烧录Arduino BootLoader的参数设置
本文仅适用于BootLoader损坏且买到国产“免驱USBasp下载线”导致Arduino IDE无法识别从而不能烧写的情况.是一种略显非主流的操作方式. 因为Arduino的IDE并不支持这种免驱的 ...
- 【Java】事件驱动模型和观察者模式
你有一件事情,做这件事情的过程包含了许多职责单一的子过程.这样的情况及其常见.当这些子过程有如下特点时,我们应该考虑设计一种合适的框架,让框架来完成一些业务无关的事情,从而使得各个子过程的开发可以专注 ...
- Kindeditor上传图片回显不出来
原因之一: 图片成功上传但是回显不出来,这个时候,要检查返回的图片地址是否加了http://这个玩意,不然会将原来的头加上图片返回地址.
- hibernate的一级缓存和二级缓存详解
hibernate为我们提供了一级缓存和二级缓存,目的是为了减少应用程序对数据库的访问次数. 一级缓存: (1)所谓一级缓存就是session级别的缓存,当我们使用他的范围是当前的session,当s ...
- TP实例化模型的两种方式 M() D()
TP框架中实例化模型的两种方式 #如果使用自己自定义的函数,那么就用D $mode=D('model'); #如果使用是系统自带的函数,那么就是用M $model=M('model');
- 最新番茄花园win7系统快速稳定版
这是最新番茄花园win7系统64位快速稳定版 V2016年2月,该系统由系统妈整理和上传,系统具有更安全.更稳定.更人性化等特点.集成最常用的装机软件,集成最全面的硬件驱动,精心挑选的系统维护工具,加 ...
- IOS获取当前地理位置文本
本文转载至 http://blog.csdn.net/lvxiangan/article/details/28101119 以下内容摘抄自网络,著作权属于原作者 方法1:使用ios自带联网查询功 ...