自己好菜啊,这道题A得好辛苦
分析:
树形dp。第一次dp是从上到下的dp,统计以1为根的期望。然后第二遍dp分析一个节点的父亲对子节点的影响。具体的操作有官方题解。我也不赘述了。
这道题坑点在第二遍dp一开始对树根的处理吧,wa得死去活来。仔细想清楚了也就能过了。
这种题我以前从来没有接触过,算盲区吧。。哎,我好菜啊
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
using namespace std;
const int maxn = 15e4 + 5;
double dp[maxn], dp2[maxn];
int deg[maxn];
vector<int> G[maxn];
void dfs(int u, int fa) {
dp[u] = 0;
int p = deg[u];
if (fa != -1) p --;
for (int v : G[u]) if (v != fa) {
dfs(v, u);
dp[u] += (dp[v] + 1) * 1.0 / p;
}
}
void dfs2(int u, int fa) {
int p = deg[u];
for (int v : G[u]) if (v != fa) {
if (fa == -1) {
if (p == 1)
dp2[v] = 1;
else
dp2[v] = ((dp[u] + 1) * p - (dp[v] + 2)) / (p - 1);
}
else
dp2[v] = ((dp2[u] + 1) + (dp[u] + 1) * (p - 1) - (dp[v] + 2)) / (p - 1);
dfs2(v, u);
}
}
int main(int argc, char const *argv[]) {
int N; cin>>N;
for (int i = 1; i < N; i ++) {
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
deg[u] ++, deg[v] ++;
}
dp2[1] = 0;
dfs(1, -1);
dfs2(1, -1);
// for (int i = 1; i <= N; i ++)
// cout<<i<<" "<<dp[i]<<" "<<dp2[i]<<" "<<deg[i]<<endl;
printf("%.8f\n", dp[1]);
for (int i = 2; i <= N; i ++) {
printf("%.8f\n", (dp[i] * (deg[i] - 1) + dp2[i]) * 1.0 / deg[i]);
}
}