树形DP题目集合
[树形DP](https://cn.vjudge.net/contest/123963#overview)
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
#include<cctype>
#include<stack>
#include<sstream>
#include<list>
#include<assert.h>
#include<bitset>
#include<numeric>
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,x,n) for(int i=(x); i<=(n); i++)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e18;
const int maxm = 1e6 + ;
const double PI = acos(-1.0);
const double eps = 1e-;
const int dx[] = {-,,,,,,-,-};
const int dy[] = {,,,-,,-,,-};
int dir[][] = {{,},{,-},{-,},{,}};
const int mon[] = {, , , , , , , , , , , , };
const int monn[] = {, , , , , , , , , , , , };
const int mod = ;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn = 1e5+;
int t,n,m,x,y;
int dp[maxn][],v[maxn],a[maxn];
int head[maxn];
struct node
{
int v,nxt;
}e[maxn*]; int tot;
void init()
{
tot=;//!
ms(head,-);
ms(dp,);
ms(v,);
}
void add(int u,int v)
{
e[tot].v=v;
e[tot].nxt=head[u];
head[u]=tot++;
}
void dfs(int u,int fa)
{
//dp[u][0]=0;
dp[u][]=a[u];
for(int i=head[u]; i!=-; i=e[i].nxt)
{
int v = e[i].v;
if(v == fa) continue;
dfs(v,u);
dp[u][] += max(dp[v][],dp[v][]);
dp[u][] += dp[v][];
}
}
int main()
{
while(~scanf("%d",&n))
{
init();
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
for(int i=;i<=n-;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
v[x]++;
}
scanf("\n0 0");
int root;
for(int i=;i<=n;i++)
{
if(!v[i])
{
root=i;
break;
}
}
dfs(root,root);
printf("%d\n",max(dp[root][], dp[root][]));
}
}
/* 【题意】 【类型】
树形DP 【分析】 【时间复杂度&&优化】 【trick】 【数据】 */
A HDU 1520 Anniversary party
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
#include<cctype>
#include<stack>
#include<sstream>
#include<list>
#include<assert.h>
#include<bitset>
#include<numeric>
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,x,n) for(int i=(x); i<=(n); i++)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e18;
const int maxm = 1e6 + ;
const double PI = acos(-1.0);
const double eps = 1e-;
const int dx[] = {-,,,,,,-,-};
const int dy[] = {,,,-,,-,,-};
int dir[][] = {{,},{,-},{-,},{,}};
const int mon[] = {, , , , , , , , , , , , };
const int monn[] = {, , , , , , , , , , , , };
const int mod = ;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn = 1e4+;
int t,n,m,x,y,w,ans;
int dp[maxn*],v[maxn],a[maxn];
int head[maxn];
struct node
{
int v,w,nxt;
}e[maxn*]; int tot;
void init()
{
tot=; //!
ms(head,-);
ms(dp,);
}
void add(int u,int v,int w)
{
e[tot].v=v;
e[tot].w=w;
e[tot].nxt=head[u];
head[u]=tot++;
}
int dfs(int u,int fa)
{
int Max=;
for(int i=head[u]; i!=-; i=e[i].nxt)
{
int v = e[i].v;
if(v == fa) continue;
if(!dp[i]) dp[i]=dfs(v,u)+e[i].w;
Max=max(Max,dp[i]);
}
return Max;
}
int main()
{
while(~scanf("%d",&n))
{
init();
for(int i=;i<=n;i++) //!
{
scanf("%d%d",&y,&w);
add(i,y, w),add(y,i, w);
}
for(int i=;i<=n;i++)
printf("%d\n",dfs(i,-));
}
}
/* 【题意】
给出一颗树,求树中的每个顶点到其他所有顶点的最大值。 【类型】
树形DP,最短路 【分析】
题目给出10000个点,否则的话Floyd也是可以跑,但是给出的是一棵树,那么我们就可以用树形dp了
1.(非两次DFS方法)
每次从需要求的节点出发,然后遍历该树,期间更新该点的最长路。但是用DP数组存最长路的时候有一个问题,就是便利的方向,如果不考虑方向的话肯定是错的,那么可以转换一下,DP数组不存点的最长路,存边的最长路,这样使用邻接链表村边的化就可以考虑到方向了。具体看代码。
2.(两次DFS方法)
首先,我们分析发现,当前一个点的最大距离只有两种来源:
一种是它到叶子节点的最大距离
一种是经过根节点的最大距离(也就是根节点到叶子节点 不经过 当前点的最大距离 + 跟到当前点的距离)
实现的话发现要求不经过当前点,所以我们求到叶子节点向上的最大距离时还要维护一个次短距离。 首先一遍dfs,求出从任意一个节点到叶子节点的最短路dp[i][0]和次段路dp[i][1],算是一个预处理。
然后,定义状态dp[i][2]从 i 点出发经过 root 节点的最短路。 状态转移方程:
dp[child][2] = max(dp[father][2],dp[child][0]+ child.cap == dp[father][0]?dp[father][1]:dp[father][0])+child.cap ;
(PS:另一种方法可以在第一次dfs时把从叶子节点到根节点经过的点标记出来,然后在第二次更新的时候如果遇到是经过的点,然后直接选择次短路,可以尝试一下) 【时间复杂度&&优化】 【trick】
dp数组必须开到1e5*2,否则TLE(不明觉厉???
有两种做法。
1、求树的直径。两遍dfs找到树的直径,根据树的直径的性质,从任意一个点出发走的最长距离,一定是到直径的端点。
2、树形dp。也就是我写的做法。首先从根节点开始往下搜,每次跟新以这个节点为根节点的最远距离和次远距离。
这样一次dfs之后,根节点的fir就是他所能达到的最远距离。
然后从根开始往下搜,如果这个点的父亲节点的最远距离需要经过这个点,那么只需比较(父亲节点的次远距离+dis)和(自己这个点的最远距离),
然后跟新这个点的次远和最远。如果不需要经过,那么比较 (父亲节点的最远距离+dis)和(自己这个点的最远距离),然后更新即可。 【数据】 */
B - Computer HDU - 2196(法1
树形DP题目集合的更多相关文章
- HDU-4616 Game 树形DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4616 比较典型的树形DP题目,f[u][j][k]表示以点u为子树,经过 j 个陷阱的最大值,其中k= ...
- SPOJ 1435 - Vertex Cover(树形DP,树的最小点覆盖)
算是个经典题目了,很模板的树形DP题目 做这个题的时候一开始就想到树形DP了,可是由于各种原因没写出来,代码太糟烂了,赛后还是改了好久才过的 dp(u,0)=sum(dp(v,1)): dp(u,1) ...
- 树形dp 入门
今天学了树形dp,发现树形dp就是入门难一些,于是好心的我便立志要发一篇树形dp入门的博客了. 树形dp的概念什么的,相信大家都已经明白,这里就不再多说.直接上例题. 一.常规树形DP P1352 没 ...
- P2279 [HNOI2003]消防局的设立 贪心or树形dp
题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状 ...
- 树形DP 复习
树形DP 树形DP:建立在树上的动态规划 一般有两种传递方式:根→叶或叶→根 前者出现在换根DP中,一般操作是求出某一个点的最优解,再通过这一个点推知其他点的最优解. 后者是树形DP的常见形式,一般树 ...
- HDOJ 4276 The Ghost Blows Light(树形DP)
Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The tomb consists of N room ...
- 【树形DP】洛谷P1352_没有上司的舞会
本人第一篇Blog,初学树形DP,心情别样鸡冻... 好了废话不多说,我们来看看题目[传送门] 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是 ...
- 树形dp(poj 1947 Rebuilding Roads )
题意: 有n个点组成一棵树,问至少要删除多少条边才能获得一棵有p个结点的子树? 思路: 设dp[i][k]为以i为根,生成节点数为k的子树,所需剪掉的边数. dp[i][1] = total(i.so ...
- 没有上司的舞会(树形DP)
题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...
随机推荐
- redis初试Not all 16384 slots are covered by nodes
按照这里的步骤玩redis集群,http://www.redis.cn/topics/cluster-tutorial.html ./src/redis-trib.rb create --replic ...
- 【Android】完善Android学习(一:API 2.3.3)
备注:之前Android入门学习的书籍使用的是杨丰盛的<Android应用开发揭秘>,这本书是基于Android 2.2API的,目前Android已经到4.4了,更新了很多的API,也增 ...
- ASP.NET和ASP的区别是什么
分析: ASP与ASP.NET是Microsoft公司在Web应用程序开发上的两项重要技术. ASP与ASP.NET区别如下: (1)开发语言不同:ASP的开发语言仅局限于使用non-type脚本语言 ...
- 51Nod 1007 正整数分组 | DP (01背包)
Input示例 5 1 2 3 4 5 Output示例 1 分析:2组的差最小,那么每一组都要接近sum/2,这样就转化成了普通的0 - 1背包了 #include <bits/stdc++. ...
- Send Email in Robot Framework Python Using Gmail
转载自:http://seleniummaster.com/sitecontent/index.php/selenium-robot-framework-menu/selenium-robot-fra ...
- Item 3 ------单例模式的几种实现方式,及优缺点
单例模式,是指一个类只有一个唯一的实例,一个类只会被实例化一次.实现这种效果,最佳的方式,编写包含单个元素的枚举类型. 单例模式的最佳实现方式-----创建一个包含单个元素的枚举类 public en ...
- bzoj 1776: [Usaco2010 Hol]cowpol 奶牛政坛——树的直径
农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.恰好有N-1条单位长度的双向道路,用各种各样的方法连接这些草地.而且从每片草地出发都可以抵达其他所 ...
- 炒鸡简单的canvas粒子(山东数漫江湖)
位图的canvas一直不会被svg比下去的原因了. 俗话说,须弥芥子,是大小之说,也有以小见大之说,颗颗粒子,足以构建宏大效果. 这是一篇炒鸡简单的canvas粒子教程,主要是讲如何粒子特效的原理,一 ...
- Python eval 函数说明
eval(str [,globals [,locals ]]) -- 函数将字符串str当成有效Python表达式来求值,并返回计算结果. 例 : eval('3+4') ==> ...
- FJOI游记(日记向 不定期更新)
emmmm说实话只是突发奇想开个blog记录记录自己的内心想法罢了.. 2017/12/22:刷了一周的计算几何..刷的死去活来..结果还是被D惨了...譬如都不会考,要考我都不会什么的...感觉内心 ...