动笔之前多想想可以节约很多时间
想象一下删掉某条边会会发生什么
就是把以为根的子树砍掉,此时满足子树内的权值是树的三分之一
但是砍掉时候,的祖先们就不能利用这些权值了,所以设置为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;
}
}
京公网安备 11010502036488号