[CF767C] Garland

[CF767C] Garland - 构造

Description

(n) 个节点的树,第 (i) 个节点权值为 (a_i (|a_i| le 100)),问是否能够删除掉两条边,使得该树分成三个不为空,并且每部分权值之和相等,无解输出 (-1) 否则输出方案

Solution

从根开始 DFS,如果子树的 siz 是 sum/3 就切掉他,并把这个 siz 置为 0

提名一个 fake sol,找到 siz=sum/3 或者 siz=2sum/3 都切掉,这样是不行的,因为这里边权有负数

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 1e6 + 5;

int siz[N], a[N], fa[N], n, root, sum;
vector<int> g[N];
vector<int> ans;

void dfs(int p, int from)
{
    siz[p] = a[p];
    for (int q : g[p])
    {
        dfs(q, p);
        siz[p] += siz[q];
    }
    if (siz[p] * 3 == sum && p != root)
    {
        ans.push_back(p);
        siz[p] -= sum / 3;
    }
}

signed main()
{
    ios::sync_with_stdio(false);

    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> fa[i] >> a[i];
        sum += a[i];
        if (fa[i] == 0)
            root = i;
        g[fa[i]].push_back(i);
    }

    dfs(root, 0);

    if (ans.size() >= 2 && sum % 3 == 0)
    {
        cout << ans[0] << " " << ans[1] << endl;
    }
    else
    {
        cout << -1 << endl;
    }
}
原文地址:https://www.cnblogs.com/mollnn/p/14615830.html