传送门

Solution

设所有节点的权重之和为 tottot,若 tottot 不能被 33 整除,则问题无解。

vv 在以 uu 为根的子树中,且以 vv 为根的子树权重和为 n3\dfrac{n}{3},则 fu=vf_u=v。如果有多个符合要求的 vv,则 fuf_u 取任意一个即可。如果 vv 不存在,则 fu=0f_u=0。dp 可求出 fuf_u。当且仅当下面两种情况,问题有解:

  1. vvuu 的儿子,且有两个或以上的 vv 满足 fvf_v 非零。答案为这两个 fvf_v
  2. fuf_u 非零,且以 uu 为根的子树权重和等于 2n3\dfrac{2n}{3}。答案为 uufuf_u

时间复杂度 O(n)O(n)

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;
}