题意:给定一棵根为1的树,在某节点 u,做son[u]次等概率选择下一个子节点,询问能到达最深节点的概率;
反过来考虑,dp[u]表示不能到达最深节点的概率,在某节点的递推时,dp[u]是 son[u] 次均失败;即 dp[u] 的son[u]次方;详见代码;
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
template<class T>void readn(T &x) {
x=0;
register char c=getchar();
register bool f=0;
while(!isdigit(c))f^=c=='-',c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
if(f)x=-x;
}
void rd() {
#ifdef Dmymax_ly
freopen("test.in","r",stdin);
#endif
}
const int N=1e6+9;
const ll mod=1e9+7;
int T,n,m,k,x,y,lev[N],ind[N],mx=0;
ll dp[N];
vector<int>v[N];
ll mod_pow(ll a,ll b){
ll res=1;
while(b){
if(b&1) res=(res*a)%mod;
a=(a*a)%mod;
b>>=1;
}return res;
}
ll inv(ll x){return mod_pow(x,mod-2)%mod;}
void dfs(int nowp,int fa) {
lev[nowp]=lev[fa]+1;
mx=max(lev[nowp],mx);
for(int i=0; i<v[nowp].size(); i++) {
int to=v[nowp][i];
if(to==fa) continue;
ind[nowp]++;
dfs(to,nowp);
}
}
void dfs2(int nowp,int fa) {
if(ind[nowp]==0) {
dp[nowp]=(lev[nowp]!=mx);
return;
}
for(int i=0; i<v[nowp].size(); i++) {
int to=v[nowp][i];
if(to==fa) continue;
dfs2(to,nowp);
}
for(int i=0; i<v[nowp].size(); i++) {
int to=v[nowp][i];
if(to==fa) continue;
dp[nowp]=(dp[nowp]+dp[to])%mod;
}
dp[nowp]=dp[nowp]*inv(ind[nowp])%mod;
dp[nowp]=mod_pow(dp[nowp],ind[nowp])%mod;
}
int main() {
rd();
readn(n);
for(int i=1; i<n; i++) {
readn(x);
readn(y);
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1,0);
dfs2(1,0);
printf("%lld",(1-dp[1]+mod)%mod);
return 0;
}