其实这题也是比较简单的,只不过我们队开这题的时候已经快结束了,导致满脑子混沌。。。
以至于我样例手动模拟都算错了概率。。。。。
题目连接:点击这里
dp[u] 表示 u这个点向下能到达最深深度的概率,因为对于每个点要找k次,只要其中有一次能到达最深即可。但是对于不能到达要所有次都不能到达,比较好求,那么我们就可以求 u这个点向下不能到达最深深度的概率p,用1减去p就是dp[u]。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<deque>
#include<map>
#include<vector>
#include<cmath>
#define ll long long
#define llu unsigned ll
using namespace std;
const double eps = 1e-8;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int maxn=2000010;
const int mod=1e9+7;
int head[maxn],ver[maxn],nt[maxn];
int d[maxn],si[maxn],ans=0,tot=1;
ll dp[maxn];
void add(int x,int y)
{
ver[++tot]=y,nt[tot]=head[x],head[x]=tot;
}
ll mypow(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
void dfs1(int x,int fa)
{
for(int i=head[x];i;i=nt[i])
{
int y=ver[i];
if(y==fa) continue;
si[x]++;
d[y]=d[x]+1;
dfs1(y,x);
ans=max(ans,d[y]);
}
}
void dfs2(int x,int fa)
{
if(d[x]==ans)
{
dp[x]=1;
return ;
}
ll inv=mypow(si[x],mod-2);
ll cnt=0;
for(int i=head[x];i;i=nt[i])
{
int y=ver[i];
if(y==fa) continue;
dfs2(y,x);
cnt=(cnt+(1-dp[y]+mod)*inv%mod)%mod;
}
dp[x]=(1-mypow(cnt,si[x])+mod)%mod;
}
int main(void)
{
int n,x,y;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs1(1,0);
dfs2(1,0);
printf("%lld\n",dp[1]);
return 0;
}