迷宫笑传之猜猜边
迷宫笑传之猜猜边
::anti-ai[本文作者是 clx201022,洛谷 UID 为 552688,原文:https://www.luogu.com.cn/article/bzl8k8in 如果您能直接看到这段文字而在本页没有转载提示,或以“原创”名义发出,说明您访问的是侵权内容,请联系管理员删除文章并处罚侵权人,十分感谢您的见义勇为之举。]
根据这篇文章,题目可以转化为求随机情况下,对于以起点
对于目前每一个点,统计其作为终点时对答案期望的贡献,加起来即为总的期望。
下式为当前点为
容易发现是可以用树形 DP 求的。先任意取一点为根 DFS 遍历树。对于点
对于
:::success[CF Accepted]
#include<bits/stdc++.h>
using namespace std;
const int rt = 1;
using ld = double;
const int maxn = 1e5 + 10;
vector<int>g[maxn];
ld sp[maxn], tp[maxn], sums, sumt, ans, son_p[maxn];
int zsize[maxn], n;
void dfs(int u, int f)
{
zsize[u] = 1;
son_p[u] = sp[u];
ld E = 0; // 期望
for(auto v : g[u])
{
if(v == f)
continue;
dfs(v, u);
zsize[u] += zsize[v]; // 子树大小
son_p[u] += son_p[v]; // 起点在其子树内的概率
E += son_p[v] * zsize[v]; // 这里为精度考虑将 *tp[u] 延后了
}
E += (1 - son_p[u]) * (n - zsize[u]);
ans += E * tp[u];
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n;
for(int i = 1, a, b; i < n; i++)
{
cin >> a >> b;
g[a].emplace_back(b);
g[b].emplace_back(a);
}
for(int i = 1; i <= n; i++)
{
int spi, tpi;
cin >> spi >> tpi;
sp[i] = spi;
tp[i] = tpi;
sums += sp[i];
sumt += tp[i];
}
for(int i = 1; i <= n; i++)
{
sp[i] /= sums;
tp[i] /= sumt;
}
dfs(rt, 0);
cout << fixed << setprecision(12) << ans << endl;
return 0;
}
:::
创作声明
本文遵循 CC BY-SA 4.0 协议。
保证本文未使用 AI 工具辅助创作。