题目链接 http://codeforces.com/problemset/problem/839/C
题意:两个人骑马旅行城市,n个城市被n-1条边相连,相互间可以互相访问。天空大雾,马从1号城市走,且每个城市最多只走一次,如果马可以到下一个没有访问过的城市,就继续走下去,每当马遇到岔路,那么它可以等概率的选择任何一座连通的下一个城市,求马最后经过城市个数的期望。
思路:
dfs,dfs的时候,保存到该城市的概率,以及路径。如果该城市是叶子节点。那么就更新一次期望。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5;
struct node{
int from;
int to;
int pre;
}e[maxn];
int head[maxn];
int idx;
int vis[maxn];
int step[maxn];
double ex = 0;
void addEdge(int from,int to){
e[idx].from = from;
e[idx].to = to;
e[idx].pre = head[from];
head[from] = idx;
idx++;
}
void dfs(int point,int nowstep,double p){
if(vis[point]){
return;
}
vis[point] =1;
if(step[point]==0)step[point]= nowstep;
int cnt = 0;
for(int i=head[point];i!=-1;i=e[i].pre){
if(!vis[e[i].to]){
cnt++;
}
}
for(int i=head[point];i!=-1;i=e[i].pre){
if(!vis[e[i].to]){
dfs(e[i].to,nowstep+1,cnt==0?p:p/cnt);
}
}
if(cnt==0){
ex += nowstep*p;
}
}
int main()
{
int n,from,to;
idx=0;
scanf("%d",&n);
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(head));
memset(step,0,sizeof(step));
for(int i=0;i<n-1;i++){
scanf("%d%d",&from,&to);
addEdge(from,to);
addEdge(to,from);
}
dfs(1,0,1.0);
printf("%.8lf\n",ex);
return 0;
}