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