傳送門:https://nanti.jisuanke.com/t/41392
題意:
從樹的根節點開始dfs(1,1),假設當前節點u的子結點有k個,則遞歸調用dfs(v,d+1)k次,每次的v都隨機從u的k個子結點中選取。問成功找到整棵樹的深度的概率是多少?
分析:
顯然,這是一道樹形dp題,只要推出轉移方程即可。比賽時沒能推出正確的轉移方程,後來看了別人的題解就懂了。
轉移方程:令,v爲當前結點u的子結點,則。
其實就是統計不能到達最深處的概率p,答案爲1-p。
代碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int P=1e9+7;
const int maxn=1e6+10;
vector<int> G[maxn];
int n,H=1;
ll qsm(ll a,ll b){
ll res=1;
while(b){
if(b&1)
res=res*a%P;
a=a*a%P;
b>>=1;
}
return res;
}
ll inv(ll k){
return qsm(k,P-2);
}
void read(){
int u,v;
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
}
void find(int u,int p,int d){
H = max(H,d);
for(int v=0;v<G[u].size();v++)
if(G[u][v]!=p)
find(G[u][v],u,d+1);
}
ll dfs(int u,int p,int d){
ll dp=0,k=0;
for(int i=0;i<G[u].size();i++)
if(G[u][i]!=p)
dp+=dfs(G[u][i],u,d+1),k++;
if(k)
return qsm(dp*inv(k)%P,k);
else
return d!=H?1:0;
}
int main(){
read();
find(1,0,1);
printf("%lld\n",(1+P-dfs(1,0,1))%P);
return 0;
}