Ant【概率】-2020百度之星初赛3

题意

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6788

分析

先求出从点 (1) 到点 (m) 的路径,要想第二只蚂蚁到达 (m) 的概率大于等于 (frac{1}{2}) ,那么该条路径上的分叉点最多 (1) 个。可以通过枚举分叉点所在位置的方法,求出概率。

当不存在分叉点时,概率直接算。如果存在一个分叉点,当为了保证第 (1) 只蚂蚁要到达 (m) 点,当它偏离正确路径之后,要能够回来。因此,它就不可以往回走。

代码

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=1e5+5;
int n,m;
int fa[N],degree[N];
vector<int>pic[N];
ll power(ll a,ll b)
{
    ll res=1;
    a%=mod;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
void dfs(int u,int p)
{
    fa[u]=p;
    if(u==m) return;
    for(int i=0;i<pic[u].size();i++)
    {
        int v=pic[u][i];
        if(v==p) continue;
        dfs(v,u);
    }
}
int main()
{
    int test,x,y;
    scanf("%d",&test);
    while(test--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            pic[i].clear();
            degree[i]=0;
        }
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            pic[x].pb(y);
            pic[y].pb(x);
            degree[x]++;
            degree[y]++;
        }
        if(m==1)
        {
            printf("1
");
            continue;
        }
        dfs(1,0);
        ll ans=0,tmp=1;
        for(int i=fa[m];i!=0;i=fa[i])//没有分叉的情况
            tmp=tmp*power(degree[i],mod-2)%mod;
        ans=tmp;
        for(int i=fa[m];i!=1;i=fa[i])
        {
            if(degree[i]>2)//不能往回走
                ans=(ans+tmp*(degree[i]-2)%mod*power(degree[i]-1,mod-2))%mod;
        }
        if(degree[1]>1) ans=(ans+tmp)%mod;
        printf("%lld
",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/1024-xzx/p/13472488.html