codeforces 839C Journey

题目链接 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;
}

猜你喜欢

转载自blog.csdn.net/qq_25955145/article/details/81479566