您的位置:首页 > 其它

CF 767C.Garland 思维,树三等分

2018-03-17 14:34 399 查看
题意:n个节点的树,第i个节点权值为a[i]. n<=1e6. -100<=a[i]<=100 

问是否能够删除掉两条边,使得该树分成三个不为空,并且每部分权值之和相等.

无解输出-1 否则输出要删除边(u->v)的v节点序号.

首先所有点的权值和sum%3要为0,令val=sum/3,f[u]为节点u的权值和

找到任意一个f[y]=val的子树y,然后删除掉子树y,在树的剩下部分中找到一个f[x]=val的x即可.
删除子树y 也就是f[fa[y]]不加上f[y]即可.

#include <bits/stdc++.h>
using namespace std;
const int N=2e6+5,M=22;
int n,rt,val,a
,f
;
vector<int> e
;
int x=-1,y=-1;
void dfs(int u,int fa)
{
f[u]=a[u];
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i];
if(v==fa) continue;
dfs(v,u);
if(y==-1&&f[v]==val)
y=v;
else
f[u]+=f[v];
}
if(f[u]==val&&y!=-1&&u!=rt)
x=u;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int u,v,sum=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>u>>v;
a[i]=v,sum+=v;
e[u].push_back(i);
if(u==0)
rt=i;
}
if(sum%3)
{
puts("-1");
return 0;
}
val=sum/3;
dfs(rt,0);
if(x!=-1)
printf("%d %d\n",x,y);
else
puts("-1");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: