CF1060F

题意

\(n\) 个点的树,每次随机选择一条边,随机删去一个点,并将这个点连的所有边连到没被删的那个点上。
问每个点最后没被删的概率是多少。

\(1\ \leq\ n\ \leq\ 50\)

做法1

对每个点单独考虑,做每个点时将这个点提为根 \(root\)。如果直接考虑每个子树和 \(root\) 删的点比较难。可以发现,一个以 \(u\) 为根的子树,在 \(u\)\(root\) 删去之前,所有点都不会被 \(root\) 删掉,会有一些点被 \(u\) 子树中的点删掉。\(u\)\(root\) 删了之后,所有子树挂在 \(root\) 下,可以将这种情况考虑为以 \(u\) 为根的子树的子问题,并且每个子树是独立的。
我们令 \(dp(u,\ i)\) 表示,\(u\) 子树中已经删掉了 \(i\) 个点,\(u\) 没被删,剩下的子树中 \(u\) 删掉所有点的概率。由于子树之间是独立的,所以转移的时候可以对于 \(u\) 的每个孩子 \(v\) 先将 \(dp(v)\) 更新成 \(v\) 被挂在一个节点下的答案,即 \(u\) 只有一个孩子 \(v\),然后合并。
考虑 \(u\) 只有一个孩子 \(v\) 的更新。若 \(v\)\(dp(u,\ i)\) 中的前 \(i\) 个点中被删去了,则贡献是 \(dp(u,\ i)\ +=\ dp(v,\ i\ -\ 1)\ \times\ i\)。否则 \(dp(u,\ i)\ +=\ \frac{1}{2}\ dp(v,\ j),\ \forall\ j\ \geq\ i\)

代码

#include <bits/stdc++.h>

#ifdef __WIN32
#define LLFORMAT "I64"
#else
#define LLFORMAT "ll"
#endif

using namespace std;

int main() {
	int n; cin >> n;
	vector<vector<int> > g(n);
	for (int u, v, i = 1; i < n; ++i) cin >> u >> v, --u, --v, g[u].push_back(v), g[v].push_back(u);
	vector<vector<long double> > dp(n); vector<long double> fac(n + 1);
	fac[0] = 1;
	for (int i = 1; i <= n; ++i) fac[i] = fac[i - 1] * i;

	auto C = [&](int n, int m) { return n < m || m < 0 ? (long double) 0 : fac[n] / fac[m] / fac[n - m]; };

	function<void(int, int)> DP = [&](int u, int p) {
		dp[u] = vector<long double>{1.0};
		for (int v: g[u]) if(v != p) {
			DP(v, u);
			vector<long double> t(dp[v].size() + 1, 0); long double s;
			for (int j = 0; j < dp[v].size(); ++j) if(s = dp[v][j]) {
				t[j + 1] += s * (j + 1);
				for (int i = 0; i <= j; ++i) t[i] += s * .5;
			}
			vector<long double> pd(t.size() + dp[u].size() - 1, 0);
			for (int i = 0; i < dp[u].size(); ++i) for (int j = 0; j < t.size(); ++j) {
				pd[i + j] += C(i + j, i) * C(dp[u].size() + dp[v].size() - 1 - (i + j), dp[u].size() - 1 - i) * t[j] * dp[u][i];
			}
			dp[u] = pd;
		}
		return;
	};

	auto solve = [&](int root) {
		DP(root, -1);
		return dp[root][0] / fac[n - 1];
	};

	for (int i = 0; i < n; ++i) cout << setprecision(8) << solve(i) << endl;
	return 0;
}
posted @ 2018-10-08 13:46  King_George  阅读(270)  评论(0编辑  收藏  举报