codeforce398div2C. Garland

 

'

 

   

    1 对树后序遍历一遍,s【i】里存的是结点i上所有子树结点权值和(包括这个结点,但不包括那些已经切去的结点)

 

从叶子往上遍历,当s【i】等于sum/3时,就在这个点切,当切去两个部分之后就不切了,最后看看剩下的部分等不等于sum/3就行了

  上代码了 QAQ

#include <algorithm>
#include <stack>
#include <istream>
#include <stdio.h>
#include <map>
#include <math.h>
#include <vector>
#include <iostream>
#include <queue>
#include <string.h>
#include <set>
#include <cstdio>
#define FR(i,n) for(int i=0;i<n;i++)
#define MAX 2005
#define mkp pair <int,int>
using namespace std;
const int maxn = 2e6+3;
typedef long long ll;

void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x << 1) + (x << 3) + ch - 48, ch = getchar());
x *= 1 - 2 * flag;
}
int n,sum=0,total[maxn];
int top=0;
vector <int> v1[maxn];
int val[maxn];
int start=-1;
int ans[5];
void dfs(int cnt,int last)
{
int k=v1[cnt].size();
// printf("%d\n",k);
for(int i=0;i<k;i++)
{
if(v1[cnt][i]!=last)
{
dfs(v1[cnt][i],cnt);
val[cnt]+=val[v1[cnt][i]];
}
}
if(val[cnt]==sum&&top<2&&cnt!=start)
{
val[cnt]=0;
ans[top++]=cnt;

}
}
int main() {
scanf("%d",&n);
memset(total,0,sizeof(total));
for(int i=1;i<=n;i++){
int l,r;
scanf("%d",&l);
if(!l)start=i;
else v1[l].push_back(i);
scanf("%d",&r);val[i]=r;
sum+=r;
}
if(sum%3){puts("-1");return 0;}
int tmp=sum;
sum/=3;
dfs(start,-1);
// for(int i=1;i<=n;i++)printf("%d ",val[i]);
// printf("%d\n",top);
if(top==2&&val[start]==sum)
{
printf("%d %d\n",ans[0],ans[1]);
}
else puts("-1");
return 0;
}

 

posted @ 2018-05-30 15:13  Xzavieru  阅读(170)  评论(0编辑  收藏  举报