#1479 : 三等分(树形DP)
http://hihocoder.com/problemset/problem/1479
#1479 : 三等分
描述
小Hi最近参加了一场比赛,这场比赛中小Hi被要求将一棵树拆成3份,使得每一份中所有节点的权值和相等。
比赛结束后,小Hi发现虽然大家得到的树几乎一模一样,但是每个人的方法都有所不同。于是小Hi希望知道,对于一棵给定的有根树,在选取其中2个非根节点并将它们与它们的父亲节点分开后,所形成的三棵子树的节点权值之和能够两两相等的方案有多少种。
两种方案被看做不同的方案,当且仅当形成方案的2个节点不完全相同。
输入
每个输入文件包含多组输入,在输入的第一行为一个整数T,表示数据的组数。
每组输入的第一行为一个整数N,表示给出的这棵树的节点数。
接下来N行,依次描述结点1~N,其中第i行为两个整数Vi和Pi,分别描述这个节点的权值和其父亲节点的编号。
父亲节点编号为0的节点为这棵树的根节点。
对于30%的数据,满足3<=N<=100
对于100%的数据,满足3<=N<=100000, |Vi|<=100, T<=10
输出
对于每组输入,输出一行Ans,表示方案的数量。
- 样例输入
-
2
3
1 0
1 1
1 2
4
1 0
1 1
1 2
1 3 - 样例输出
-
1
0
参考博客:http://blog.csdn.net/viphong/article/details/61958631
需要两个dfs,第一个dfs从父节点开始递归遍历,求出以每个节点为根的子树的权值和。
第二个dfs就是开始统计个数: 若某一节点正好是总数的1/3,那么该节点很有可能和另一个节点符合题目要求,那么另一个节点就是另一个1/3节点,或者另一个节点是该节点祖先节点,这个祖先节点是总数的2/3#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int Max = + ;
int v[Max], sum[Max];
long long all, first, second, cnt, root;
vector<int> mp[Max];
//统计每个子树的权值和
void dfs(int node, int fa)
{
sum[node] = v[node];
for (int i = ; i < (int)mp[node].size(); i++)
{
int son = mp[node][i];
if (son != fa)
{
dfs(son, node);
sum[node] += sum[son];
}
}
}
// 核心
void dfs2(int node, int fa)
{
//找到一个1/3节点
if (sum[node] == all)
cnt += first + second;
// 因为可能有负数,所有要继续往下递归
if (sum[node] == all * && node != root)
second++; for (int i = ; i < (int)mp[node].size(); i++)
{
int son = mp[node][i];
if (son != fa)
{
dfs2(son, node);
}
}
//每一个1/3的节点只会和另一个不同分支的1/3节点满足条件
//每一个1/3的节点只会和它祖先是2/3的满足条件
if (sum[node] == all)
first++;
//以node为根节点满足2/3,全都遍历完毕,所以再不存在以node为根与一个1/3节点满足条件,故删除该2/3节点
if (sum[node] == all * && node != root)
second--;
}
int main()
{
int n, t, fa;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
//清空
for (int i = ; i <= n; i++)
mp[i].clear();
memset(sum, , sizeof(sum));
cnt = all = first = second = ;
for (int i = ; i <= n; i++)
{
scanf("%d%d", &v[i], &fa);
all += v[i];
if (fa == )
root = i;
mp[fa].push_back(i);
}
if (all % )
{
printf("0\n");
continue;
}
all /= ;
dfs(root, );
dfs2(root, );
printf("%lld\n", cnt);
}
return ;
}
#1479 : 三等分(树形DP)的更多相关文章
- Hihocoder #1479 : 三等分 树形DP
三等分 描述 小Hi最近参加了一场比赛,这场比赛中小Hi被要求将一棵树拆成3份,使得每一份中所有节点的权值和相等. 比赛结束后,小Hi发现虽然大家得到的树几乎一模一样,但是每个人的方法都有所不同.于 ...
- SPOJ 1479 +SPOJ 666 无向树最小点覆盖 ,第二题要方案数,树形dp
题意:求一颗无向树的最小点覆盖. 本来一看是最小点覆盖,直接一下敲了二分图求最小割,TLE. 树形DP,叫的这么玄乎,本来是线性DP是线上往前\后推,而树形DP就是在树上,由叶子结点状态向根状态推. ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
- POJ2342 树形dp
原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...
随机推荐
- 【数学建模】day07-数理统计II
方差分析和回归分析. 用数理统计分析试验结果.鉴别各因素对结果影响程度的方法称为方差分析(Analysis Of Variance),记作 ANOVA. 比如:从用不同工艺制作成的灯泡中,各自抽取了若 ...
- Redis宕机的问题
在主从模式下宕机要分为区分来看: slave从redis宕机 在Redis中从库重新启动后会自动加入到主从架构中,自动完成同步数据: 如果从数据库实现了持久化,只要重新假如到主从架构中会实现增 ...
- VSCode里面HTML添加CSS时没有提示
看到知乎上的回答,vscode修改设置的: "editor.parameterHints": true, "editor.quickSuggestions": ...
- BZOJ4912 SDOI2017天才黑客(最短路+虚树)
容易想到把边当成点重建图跑最短路.将每条边拆成入边和出边,作为新图中的两个点,由出边向入边连边权为原费用的边.对于原图中的每个点,考虑由其入边向出边连边.直接暴力两两连边当然会被卡掉,注意到其边权是t ...
- wstngfw openVpn站点到站点连接示例(共享密钥)
wstngfw openVpn站点到站点连接示例(共享密钥) 在本例中,将假设以下设置: 站点 A 站点 B 名称 Beijing Office(北京办公室) 名称 Shenzheng Office( ...
- wstngfw 初始化的一些配置
wstngfw 初始化的一些配置 1. 引导界面 2. 命令行菜单界面 3. Assign Interfaces (分配接口) Should VLANs be set up now [y|n]? nW ...
- Android studio preview界面无法预览,报错render problem
1.查看报错信息,如果有报错,该叹号应为红色,点击查看报错,显示为render problem 2.打开res/styles.xml修改为如图,添加Base. 3.再打开preview界面
- ubuntu配置mysql
1.安装mysql: sudo apt-get install mysql-server sudo apt-get install mysql-client sudo apt-get install ...
- jmeter4.0测试dubbo接口遇到的问题:An error occurred: org.springframework.scheduling.quartz.CronTriggerBean has interface org.quartz.CronTrigger as super class
半年前,用jmeter4.0测试dubbo接口的时候,遇到这样一个问题 An error occurred: org.springframework.scheduling.quartz.CronTri ...
- DNA Evolution CodeForces - 828E(树状数组)
题中有两种操作,第一种把某个位置的字母修改,第二种操作查询与[L, R]内与给出字符串循环起来以后对应位置的字母相同的个数.给出的字符串最大长度是10. 用一个四维树状数组表示 cnt[ATCG的编号 ...