地址:http://hihocoder.com/problemset/problem/1479

题目:

三等分

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小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
思路:哈希+dfs
两遍dfs,第一遍求出到该点的权值和(sum[x]:权值和),第二遍时计算答案ans。
因为只有三等分,其中一个点已经规定了是根节点,所以只需考虑剩下两个点(选作根)的情况:
1.两个点是祖先关系,两点在同一条链上。
2.两点不在同一条链上。
对于这两种情况,我们可以两个哈希来解决
对于第一种情况:维护一个map<int,int>fa的哈希,该哈希记录的是到节点x的所有祖先节点的权值和,则可以三等分时有sum[root]==3*sum[x]?ans+=fa[2*sum[x]]:0;
对于第二种情况:同样是维护一个哈希map<int,int>hs,该哈希记录的是除节点的x的祖先节点外已dfs过的节点的权值和,则可以三等分时有sum[root]==3*sum[x]?ans+=hs[sum[x]]:0;
综上:
if(sum[root]==3*sum[x])
  ans+=fa[2*sum[x]]+hs[sum[x]]; 另外一种做法,dp!
dp[x][i]:表示到节点x时,合法的i等分的情况有多少种。
然后考虑下子树合并时的情况就好了。
这种方法可以解决n等分问题,第一种方法不能。
 #include <bits/stdc++.h>

 using namespace std;

 #define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int,int> PII;
const double eps=1e-;
const double pi=acos(-1.0);
const int K=1e6+;
const int mod=1e9+; int n,v[],sum[];
vector<int>mp[];
map<int,int>hs,fa;
LL ans;
void dfs1(int x)
{
sum[x]=v[x];
for(int i=;i<mp[x].size();i++)
dfs1(mp[x][i]),sum[x]+=sum[mp[x][i]];
}
void dfs2(int x,int f)
{
if(x!=f&&sum[f]==*sum[x]) ans+=fa[sum[x]*]+hs[sum[x]];
if(x!=f)fa[sum[x]]++;
for(int i=;i<mp[x].size();i++)
{
int u=mp[x][i];
dfs2(u,f),hs[sum[u]]++;
}
if(x!=f)fa[sum[x]]--;
}
int main(void)
{
int t;cin>>t;
while(t--)
{
ans=;
memset(sum,,sizeof(sum));
hs.clear(),fa.clear();
memset(mp,,sizeof(mp));
cin>>n;
for(int i=,x;i<=n;i++)
scanf("%d%d",&v[i],&x),mp[x].PB(i);
dfs1(mp[][]);
if(sum[mp[][]]%==)
dfs2(mp[][],mp[][]);
cout<<ans<<endl;
}
return ;
}
/*
123
13
0 0
-1 1
1 2
-1 3
1 4
-1 5
1 6
-1 1
1 8
-1 9
1 10
-1 11
1 12
7
0 0
0 1
0 2
0 3
0 1
0 5
0 6
5
0 0
0 1
0 1
0 1
0 1
9
0 0
0 1
0 2
0 1
0 4
0 1
0 6
0 1
0 8
*/
 

hihocoder1479 三等分的更多相关文章

  1. ios用xib实现三等分以及多等分思路

    Auto Layout 的本质原理 Auto Layout 的本质是用一些约束条件对元素进行约束,从而让他们显示在我们想让他们显示的地方. 约束主要分为以下几种(欢迎补充): 相对于父 view 的约 ...

  2. #1479 : 三等分(树形DP)

    http://hihocoder.com/problemset/problem/1479 #1479 : 三等分 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi最 ...

  3. css等比例分割父级容器(完美三等分)

    html部分代码: 方法一: 浮动布局+百分比 (将子元素依次左浮动,根据子元素的个数,设定每个子元素的宽度百分比) 方法二:行内元素(inline-block)+百分比 方法三: 父元素  disp ...

  4. Hihocoder #1479 : 三等分 树形DP

    三等分  描述 小Hi最近参加了一场比赛,这场比赛中小Hi被要求将一棵树拆成3份,使得每一份中所有节点的权值和相等. 比赛结束后,小Hi发现虽然大家得到的树几乎一模一样,但是每个人的方法都有所不同.于 ...

  5. canvas绘制三等分饼型图

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. [Swift]LeetCode927. 三等分 | Three Equal Parts

    Given an array A of 0s and 1s, divide the array into 3 non-empty parts such that all of these parts ...

  7. bash编程 将一个目录里所有文件存为一个array 并分割为三等分——利用bash array切片

    files=(a b c d e f g h i j k l m n o p)cnt="${#files[@]}"let cnt1="($cnt+2)/3"le ...

  8. 【[Offer收割]编程练习赛9 C】三等分

    [题目链接]:http://hihocoder.com/problemset/problem/1479 [题意] . [题解] 首先算出所有节点的权值的和val; 然后如果val%3!=0则直接输出0 ...

  9. 【css3笔记】---- 渐变的秘密

    <CSS揭秘>这本书非常不错,充满了干货和惊喜.以下主要是关于使用渐变做出来的一些效果的笔记.请用最新的现代浏览器观看. 首先要回顾下一个css语句: linear-gradient([ ...

随机推荐

  1. [转]Loadrunner Error code 10053 & Tomcat 连接器(connector)优化

    LoadRunner提示错误:Error : socket0 - Software caused connection abort. Error code : 10053. 在今天的测试过程中发现,s ...

  2. C++ STL迭代器与索引相互转换

    0 前言 C++ STL提供了vector.list等模板容器,极大地方便了编程使用. “遍历”是对容器使用的最常用的操作. 使用迭代器来遍历是最好最高效的遍历方法. 当然,对于有些容器的遍历除了使用 ...

  3. 1-2、superset国际化

    最近由于工作需要研究开源可视化项目superset,由于其国际化做不怎么好,故而记录下国际化的过程,本篇本着『授人以鱼不如授人以渔』的原则,只叙述国际化的过程及方法,不提供直接的国际化文件. 为了方便 ...

  4. studio导入Eclipse 项目要改的文件

    添加下面文件即可,一个不能少 1. project 2.project.properties 3.classpath 4.AndroidManifest.xml 以上目录都有可以正常导入studio中

  5. 用Java实现自己的ArrayList

    利用自己对ArrayList的理解,重写了Java的ArrayList工具类,旨在理解源码的精髓: public class MyArrayList<T> { //成员变量 private ...

  6. JS-表单提交检查表单字数方法

    解决方法: //作用于整个html中 function check(form) { //topic是input的id,descrip是textarea的id var topic = $("# ...

  7. SQL ALTER TABLE 命令

    SQL ALTER TABLE 命令 SQL ALTER TABLE 命令用于添加.删除或者更改现有数据表中的列. 你还可以用 ALTER TABLE 命令来添加或者删除现有数据表上的约束. 语法: ...

  8. poj_2559 单调栈

    题目大意 给出一个柱形图中柱子的高度,每个柱子的宽度为1,柱子相邻.求出柱形图中可能形成的矩形的最大面积. 题目分析 以每个柱子(高度为h[i])为中心,向两边延展求出以该h[i]为高度的矩形的最大宽 ...

  9. iOS消息推送证书创建过程

    iOS消息推送证书创建过程 一.创建证书请求 1.在mac上进行钥匙串访问(keychain) 2. 选择钥匙串访问>证书助理> 从证书颁发机构中请求一个证书,如图1所示 图1 3.输入你 ...

  10. java URL、HTTP与HTML+CSS

    一.Web三大基石 1 二.API(Application Programming Interface,应用程序编程接口) 1 三.题目分析总结: 3 五.HTTP协议与寄信是类似的 6 请求报文 6 ...