题目链接:https://nanti.jisuanke.com/t/41392
题解:dp[u] 表示 u这个点向下能到达最深深度的概率,因为对于每个点要找k次,只要其中有一次能到达最深即可,所以我们用容斥的思想,即表示为 1 - 不能到达最深的概率,不能到达最深的概率就是k次都不能到达最深。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const ll mod = 1e9 + 7;
vector<int> v[N];
int n;
int maxx, dep[N];
ll dp[N];
void dfs(int u, int fa ) {
dep[u] = dep[fa] + 1;
maxx = max(maxx, dep[u]);
int to;
for(int i = 0; i < v[u].size(); i++) {
to = v[u][i];
if(to == fa) continue;
dfs(to, u);
}
}
ll ksm(ll x, ll y) {
ll res = 1;
while(y) {
if(y & 1) res = res * x % mod;
y >>= 1;
x = x * x % mod;
}
return res;
}
void dfs1(int u, int fa) {
int flag = 0;
ll cnt = 0;
ll len = v[u].size();
if(u != 1) len--;
ll tmp = ksm(len, mod - 2);
ll d;
int to;
for(int i = 0; i < v[u].size(); i++) {
to = v[u][i];
if(to == fa) continue;
dfs1(to, u);
cnt = (cnt + (1 - dp[to] + mod) % mod * tmp % mod) % mod;
flag = 1;
}
if(flag == 0) {
if(dep[u] == maxx)
dp[u] = 1;
} else {
dp[u] = (1 - ksm(cnt, len) % mod + mod) % mod;
}
}
int main() {
scanf("%d", &n);
int x, y;
for(int i = 1; i < n; i++) {
scanf("%d %d", &x, &y);
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1, 1);
dfs1(1, 1);
printf("%lld\n", dp[1]);
return 0;
}