Solution
设所有节点的权重之和为 ,若 不能被 整除,则问题无解。
设 在以 为根的子树中,且以 为根的子树权重和为 ,则 。如果有多个符合要求的 ,则 取任意一个即可。如果 不存在,则 。dp 可求出 。当且仅当下面两种情况,问题有解:
- 设 是 的儿子,且有两个或以上的 满足 非零。答案为这两个 。
- 非零,且以 为根的子树权重和等于 。答案为 和 。
时间复杂度 。
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, a[N], fa[N], sum[N], f[N], tot;
vector<int> g[N];
void dfs(int u)
{
sum[u] = a[u];
for (int v : g[u]) {
dfs(v);
sum[u] += sum[v];
if (f[v]) {
if (!f[u])
f[u] = f[v];
else {
printf("%d %d", f[u], f[v]);
exit(0);
}
}
}
if (sum[u] == tot * 2 && f[u] && fa[u]) {
printf("%d %d", f[u], u);
exit(0);
}
if (sum[u] == tot)
f[u] = u;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &fa[i], &a[i]);
g[fa[i]].push_back(i);
tot += a[i];
}
if (tot % 3) {
printf("-1");
return 0;
}
tot /= 3;
dfs(g[0][0]);
printf("-1");
return 0;
}