codeforces 123E. Maze (概率与期望)

E. Maze
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

A maze is represented by a tree (an undirected graph, where exactly one way exists between each pair of vertices). In the maze the entrance vertex and the exit vertex are chosen with some probability. The exit from the maze is sought by Deep First Search. If there are several possible ways to move, the move is chosen equiprobably. Consider the following pseudo-code:

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) is the list vertices adjacent to x. The flag array is initially filled as FALSEDFS initially starts with a parameter of an entrance vertex. When the search is finished, variable count will contain the number of moves.

Your task is to count the mathematical expectation of the number of moves one has to do to exit the maze.

Input

The first line determines the number of vertices in the graph n (1 ≤ n ≤ 105). The next n - 1 lines contain pairs of integers ai and bi, which show the existence of an edge between ai and bi vertices (1 ≤ ai, bi ≤ n). It is guaranteed that the given graph is a tree.

Next n lines contain pairs of non-negative numbers xi and yi, which represent the probability of choosing the i-th vertex as an entrance and exit correspondingly. The probabilities to choose vertex i as an entrance and an exit equal  and correspondingly. The sum of all xi and the sum of all yi are positive and do not exceed 106.

Output

Print the expectation of the number of moves. The absolute or relative error should not exceed 10 - 9.

Examples
input
2
1 2
0 1
1 0
output
1.00000000000000000000
input
3
1 2
1 3
1 0
0 2
0 3
output
2.00000000000000000000
input
7
1 2
1 3
2 4
2 5
3 6
3 7
1 1
1 1
1 1
1 1
1 1
1 1
1 1
output
4.04081632653
Note

In the first sample the entrance vertex is always 1 and the exit vertex is always 2.

In the second sample the entrance vertex is always 1 and the exit vertex with the probability of 2/5 will be 2 of with the probability if 3/5 will be 3. The mathematical expectations for the exit vertices 2 and 3 will be equal (symmetrical cases). During the first move one can go to the exit vertex with the probability of 0.5 or to go to a vertex that's not the exit vertex with the probability of 0.5. In the first case the number of moves equals 1, in the second one it equals 3. The total mathematical expectation is counted as2 / 5 × (1 × 0.5 + 3 × 0.5) + 3 / 5 × (1 × 0.5 + 3 × 0.5)



题目大意:

一个迷宫是一棵树(即一张无向图,其中任意两点之间仅有一条路径)。迷宫的起点和终点都按照某种概率随机选取。人们会在迷宫中用深度优先搜索的方法搜寻终点。如果有许多条可能的路径,会等概率地选取一条。考虑如下伪代码:

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的值就是在迷宫中走的步数。

你的任务是计算在迷宫中从入口到出口,所走的期望步数。

对于每个点会给出两个值xi,yi,点i作为入口的概率是xi/sigma(xi),作为出口的概率是yi/sigma(yi) 

题解:概率与期望

我们考虑每条边经过的次数,假设此时的起终点为s,t。

如果某条边在s->t的路径上,那么这条边一定会经过一次。因为到达t后就不会再继续dfs了。

如果不在s->t的路径上,那么这条边可能经过0或2次。那么经过的期望为多少呢?

设与在必经路径上且与这条边最近的节点为u,而这条边在u的儿子v的子树中,而终点在u的儿子w的子树中。

如果先走w,那么这条边就没有机会经过,如果先走v,那么这条边必然会经历两次。

因为遍历的顺序是等概率的,所以先后遍历的概率都是1/2,所以这条边的期望就是1.

综上所述在起点到达终点之前可能经过的每一条边的期望都是1.

那么我们现在要考虑不同s,t的问题,如果直接暴力每条路径必然不行。我们考虑如果当前点x为终点,那么当起点在x的子树中是,从子树向上到达x就会停止,所以可能经过的边数就是起点所属的x的儿子的size,那么期望就是size*子树中点作为起点的总概率*x为终点的概率。

如果起点在x的子树之外,那么x的子树都没有机会遍历到,而剩下的边都有可能被经过,所以对答案的贡献是(n-size)*(sigma(xi)-sigma(x的子树))*x为终点的概率。

#include
#include
#include
#include
#include
#define N 200003
using namespace std;
int n,point[N],next[N],v[N],size[N],tot;
double ex[N],en[N],sumx,sumn,ans;
void add(int x,int y)
{
	tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y;
	tot++; next[tot]=point[y]; point[y]=tot; v[tot]=x;
//	cout<



你可能感兴趣的:(概率与期望)