动笔之前多想想可以节约很多时间
想象一下删掉某条边会会发生什么
就是把以为根的子树砍掉,此时满足子树内的权值是树的三分之一
但是砍掉时候,的祖先们就不能利用这些权值了,所以设置为0
就这样一遍回溯就可以解决
亏我还想了那么久......彩笔
#include <bits/stdc++.h> using namespace std; const int maxn=2e6+10; int f[maxn],root,a[maxn],su,c[maxn]; int ans,q,w; struct edge{ int to,nxt; }d[maxn]; int head[maxn],cnt=1; void add(int u,int v){ d[++cnt]=(edge){v,head[u]},head[u]=cnt; } void dfs1(int u,int fa) { for(int i=head[u];i;i=d[i].nxt ) { int v=d[i].to; if( v==fa ) continue; dfs1(v,u); f[u]+=f[v]; } if( f[u]==su ) { ans++; f[u]=0; if( q&&!w ) w=u; else if( !q&&!w ) q=u; } } int main() { int n,m,sumn=0; cin >> n ; for(int i=1;i<=n;i++) { int x; scanf("%d%d",&x,&f[i]); sumn+=f[i]; if( x==0 ) root=i; else add(x,i), add(i,x); } if( sumn%3!=0 ) cout << -1; else { su=sumn/3; dfs1(root,0); if( ans>=3) cout << q << " " << w; else cout << -1; } }