qscoj:喵哈哈村的卢西奥

喵哈哈村的卢西奥

发布时间: 2017年3月13日 12:13   时间限制: 1000ms   内存限制: 128M

描述

为了拯救喵哈哈村,这个世界必须要存在英雄。

一名叫做卢西奥的英雄站了出来!他现在面临一个难题:

他被要求将一棵树拆成3份,使得每一份中所有节点的权值和相等。

他希望知道,对于一棵给定的有根树,在选取其中2个非根节点并将它们与它们的父亲节点分开后,所形成的三棵子树的节点权值之和能够两两相等的方案有多少种。

两种方案被看做不同的方案,当且仅当形成方案的2个节点不完全相同。

输入

每个输入文件包含多组输入,在输入的第一行为一个整数T,表示数据的组数。

每组输入的第一行为一个整数N,表示给出的这棵树的节点数。

接下来N行,依次描述结点1~N,其中第i行为两个整数Vi和Pi,分别描述这个节点的权值和其父亲节点的编号。

父亲节点编号为0的节点为这棵树的根节点。

满足3<=N<=100000, |Vi|<=100, T<=10

输出

对于每组输入,输出一行Ans,表示方案的数量。

样例输入1  复制
2
3
1 0
1 1
1 2
4
1 0
1 1
1 2
1 3
样例输出1
1
0


sum[u]:以u点为根的子树所有节点权值之和

树的总权值为sum[root],既然是平均分成三分那么每一分的值一定是sum[root]/3

总共有两种情况:

①两个切割点属于不同子树

②其中一个切割点在以另一个切割点为根的子树中

对于①:深搜时统计一下就好了

对于②:即是需要找到一个点sum[x] = sum[root]*2/3,并且在以x点为根的子树中有点满足sum[p] = sum/3,也在深

统计一下就好


http://qscoj.cn/problem/43/

#include
#include
#include
using namespace std;
#define LL long long
vector G[100005];
LL ans, sum[100005], df, sa;
int root, n, val, pri[100005];
LL Jud(int u, int p)
{
	int i, v;
	sum[u] += pri[u];
	for(i=0;i


你可能感兴趣的:(#,各种水题)