hdu 4705 Y (树形dp)

Description

Input

4
1 2
1 3
1 4

题目的意思是给你一棵树,让你找到所有不在一条路径上的三个点的情况个数。乍一看正向处理比较麻烦,我们从反方向考虑,如果是取在一条路径上的3个点,那又该怎样取呢?我们以Num[rt]表示以rt为根的子树上的节点的个数(包括根节点)。选取方法是这样的,先把一个树的树根选上,然后看他每一个亲儿子作为树根时,子树有几个节点(Num[son1],Num[son2],Num[son3]...)对于son1来说,能选取Num[son1]中的任意一点,再加上rt,现在选了两个点现在寻找第三个点,第三个点是剩下的所有节点随意取一个。及Num[son1]*(n-Num[son1]-1)。当我们算到son2时,结果可就不是Num[son2]*(n-Num[son2]-1)了,因为这样会与son1得到的结果重复一部分,应该是Num[son2]*(n-Num[son2]-Num[son1]-1),以此类推son3得到Num[son3]*(n-Num[son3]-Num[son2]-Num[son1]-1)。发现我们只需要用temp标记已经使用过的Num[son]的个数,对于每个son得到Num[son]*(n-temp-Num[son]-1),最后加起来就行了。PS:本题巨坑!!!!!long long 大发好!!
时间: 2024-08-05 05:38:39

hdu 4705 Y (树形dp)的相关文章

HDOJ 4705 Y 树形DP

DP:求出3点构成链的方案数 ,然后总方案数减去它 Y Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1738    Accepted Submission(s): 493 Problem Description Sample Input 4 1 2 1 3 1 4 Sample Output 1 Hint 1. The only

HDU 2196Computer(树形DP)

给你一颗边带权值的树,求树上的每一点距离其最远的一个点的距离 比较典型的题了,主要方法是进行两次DFS,第一次DFS求出每一个点距离它的子树的最远距离和次远距离,然后第二次DFS从父节点传过来另一侧的树上的距离它的最远距离进行一次比较便可得出任意点的最远距离了 之所以需要记录最远和次远是为了辨别父节点的最远距离是否是根据自己得来,如果是的话应该选择父节点的次远距离,保证结果的准确性 1 //#pragma comment(linker,"/STACK:102400000,102400000&qu

hdu 1011(树形dp)

Mark.看着吴神博客写的,还未完全懂. 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string>

HDU 2196 Computer 树形DP经典题

链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问每台电脑和其它电脑的最远距离是多少. 思路:这是一道树形DP的经典题目.须要两次DFS,第一次DFS找到树上全部的节点在不同子树中的最远距离和次远的距离(在递归中进行动态规划就可以),第二次DFS从根向下更新出终于答案.对于每次更新到的节点u,他的最远距离可能是来自u的子树,或者是u的父亲节点的最远

HDU 3899 简单树形DP

题意:一棵树,给出每个点的权值和每条边的长度, 点j到点i的代价为点j的权值乘以连接i和j的边的长度.求点x使得所有点到点x的代价最小,输出 虽然还是不太懂树形DP是什么意思,先把代码贴出来把. 这道题目的做法是:先进行一次DFS,以每个节点为根,求出它下面节点到它的数量和. 再进行一次DFS,以每个节点为根,求出它下面节点到它的花费总和. source code: #pragma comment(linker, "/STACK:16777216") //for c++ Compile

HDU 4714 Tree2cycle (树形DP)

题意:给定一棵树,断开一条边或者接上一条边都要花费 1,问你花费最少把这棵树就成一个环. 析:树形DP,想一想,要想把一棵树变成一个环,那么就要把一些枝枝叶叶都换掉,对于一个分叉是大于等于2的我们一定要把它从父结点上剪下来是最优的, 因为如果这样剪下来再粘上花费是2(先不管另一端),如果分别剪下来再拼起来,肯定是多花了,因为多了拼起来这一步,知道这,就好做了.先到叶子结点, 然后再回来计算到底要花多少. 代码如下: #pragma comment(linker, "/STACK:10240000

HDU 4313 Matrix 树形dp

题意: 给定n个点的树,m个黑点 以下n-1行给出边和删除这条边的费用 以下m个黑点的点标[0,n-1] 删除一些边使得随意2个黑点都不连通. 问删除的最小花费. 思路: 树形dp 每一个点有2个状态,成为黑点或白点. 若本身这个点就是黑点那么仅仅有黑点一种状态. 否则能够觉得是子树中某个黑点转移上来. 所以dp[i][0]是i点为黑点的状态. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <st

HDU 2196 Computer 树形DP 经典题

给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权,放在数组cost中 令tree(i)表示以节点i为根的子树 对于节点i,离该节点最远的点要不就是在tree(i)中,要不就是在father(i)上面 令: dp[i][1] : 在子树tree(i)中,离i最远的距离 dp[i][2] : 在子树tree(i)中,离i第二远的距离 (递推的时候需要)

hdu 5148 Cities(树形dp)

题目链接:hdu 5148 Cities dp[i][j]表示以i为根节点,选j个最优值,每条边被选中的时候就计算出被经过的次数,并乘上权值. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; typedef pair<int, int> pii; typedef long long ll; const