题目链接:Codeforces - Garland
每个联通块的和肯定为sum/3
然后只要找到一个子树和为sum/3,那么切开。最后判断能不能切两次即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e6+10;
int n,a[N],sum,rt,s[N];
vector<int> g[N],v;
void dfs(int x){
s[x]=a[x];
for(auto to:g[x]){
dfs(to); s[x]+=s[to];
}
if(x!=rt&&s[x]*3==sum){
v.push_back(x); s[x]=0;
}
}
signed main(){
cin>>n;
for(int i=1,fa;i<=n;i++){
scanf("%d %d",&fa,&a[i]); sum+=a[i];
if(!fa) rt=i;
else g[fa].push_back(i);
}
if(sum%3) return puts("-1"),0;
dfs(rt);
if(v.size()<2) return puts("-1"),0;
cout<<v[0]<<' '<<v[1];
return 0;
}