题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4616

  比较典型的树形DP题目,f[u][j][k]表示以点u为子树,经过 j 个陷阱的最大值,其中k=0表示从u点出发,k=1表示终点为点u。则转移方程为:f[u][j+is_rtap][k]=Max{ f[v][j][k] | v为u的儿子节点,0<=j<=m }。要分别对每颗子树求出最大值,枚举其中的两颗子树,一颗出,一颗进,更新最大值。要注意在更新k=0时的最大值是,j要从1开始遍历,因为如果当前u节点存在trap,而u中的其中一个子节点v没有trap,那么会使f[u][1][0]加上f[v][0][0]的值,而不满足题目中遇到满足的m后停止下来。

 //STATUS:C++_AC_93MS_5540KB
#include <functional>
#include <algorithm>
#include <iostream>
//#include <ext/rope>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
//using namespace __gnu_cxx;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef __int64 LL;
typedef unsigned __int64 ULL;
//const
const int N=,M=;
const int INF=0x3f3f3f3f;
const int MOD=,STA=;
const LL LNF=1LL<<;
const double EPS=1e-;
const double OO=1e15;
const int dx[]={-,,,};
const int dy[]={,,,-};
const int day[]={,,,,,,,,,,,,};
//Daily Use ...
inline int sign(double x){return (x>EPS)-(x<-EPS);}
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
//End struct Edge{
int u,v;
}e[N<<];
int first[N],next[N<<],tr[N];
int T,n,m,mt;
LL f[N][][],w[N],ans; void adde(int a,int b)
{
e[mt].u=a,e[mt].v=b;
next[mt]=first[a],first[a]=mt++;
e[mt].u=b,e[mt].v=a;
next[mt]=first[b],first[b]=mt++;
} void dfs(int u,int fa)
{
int i,j,k,v;
for(i=first[u];~i;i=next[i]){
v=e[i].v;
if(v==fa)continue;
dfs(v,u);
for(j=;j<=m;j++){
for(k=;k+j<=m;k++){
if(j<m)ans=Max(ans,f[u][j][]+f[v][k][]);
if(k<m)ans=Max(ans,f[u][j][]+f[v][k][]);
if(j+k<m)ans=Max(ans,f[u][j][]+f[v][k][]);
}
}
for(j=;j+tr[u]<=m;j++){
if(j && tr[u]<m)f[u][j+tr[u]][]=Max(f[u][j+tr[u]][],f[v][j][]+w[u]);
if(j<m)f[u][j+tr[u]][]=Max(f[u][j+tr[u]][],f[v][j][]+w[u]);
}
}
} int main()
{
// freopen("in.txt","r",stdin);
int i,j,a,b;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
mem(f,);
for(i=;i<n;i++){
scanf("%I64d%d",&w[i],&tr[i]);
f[i][tr[i]][]=f[i][tr[i]][]=w[i];
}
mt=;mem(first,-);
for(i=;i<n;i++){
scanf("%d%d",&a,&b);
adde(a,b);
} ans=;
dfs(,-); printf("%I64d\n",ans);
}
return ;
}

HDU-4616 Game 树形DP的更多相关文章

  1. HDU 2196.Computer 树形dp 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  2. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

  3. hdu 6201 【树形dp||SPFA最长路】

    http://acm.hdu.edu.cn/showproblem.php?pid=6201 n个城市都在卖一种书,该书的价格在i城市为cost[i],商人打算从某个城市出发到另一个城市结束,途中可以 ...

  4. HDU 2196 Computer 树形DP 经典题

    给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...

  5. hdu 4081 最小生成树+树形dp

    思路:直接先求一下最小生成树,然后用树形dp来求最优值.也就是两遍dfs. #include<iostream> #include<algorithm> #include< ...

  6. HDU 3899 简单树形DP

    题意:一棵树,给出每个点的权值和每条边的长度, 点j到点i的代价为点j的权值乘以连接i和j的边的长度.求点x使得所有点到点x的代价最小,输出 虽然还是不太懂树形DP是什么意思,先把代码贴出来把. 这道 ...

  7. HDU 4714 Tree2cycle (树形DP)

    题意:给定一棵树,断开一条边或者接上一条边都要花费 1,问你花费最少把这棵树就成一个环. 析:树形DP,想一想,要想把一棵树变成一个环,那么就要把一些枝枝叶叶都换掉,对于一个分叉是大于等于2的我们一定 ...

  8. hdu Anniversary party 树形DP,点带有值。求MAX

    Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  9. HDU 4313 Matrix 树形dp

    题意: 给定n个点的树,m个黑点 以下n-1行给出边和删除这条边的费用 以下m个黑点的点标[0,n-1] 删除一些边使得随意2个黑点都不连通. 问删除的最小花费. 思路: 树形dp 每一个点有2个状态 ...

  10. HDU - 2196(树形DP)

    题目: A school bought the first computer some time ago(so this computer's id is 1). During the recent ...

随机推荐

  1. django 的mysql数据配置

    原地址:http://blog.csdn.net/gamesofsailing/article/details/21465327 在成功安装python-mysql后,开始配置django的mysql ...

  2. 线索二叉树Threaded binary tree

    摘要   按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排序为一个线性序列.在该序列中,除第一个结点外每个结点有且仅有一个直接前驱结点:除最后一个结点外每一个结点有且仅有一个直接后继结点.这 ...

  3. CodeForces 300A Array

    http://codeforces.com/problemset/problem/300/A 题意 :给你n个数字,让你分成3组,第一组各个数之积要小于0,第二组要大于0,第三组要等于0,符合要求的答 ...

  4. codeforces #305 B Mike and Feet

    跟之前做过的51Nod的移数博弈是一样的QAQ 我们考虑每个数的贡献 定义其左边第一个比他小的数的位置为L 定义其右边第一个比他小的数的位置为R 这个可以用排序+链表 或者 单调队列 搞定 那么对于区 ...

  5. 情人节红攻瑰--Delphi版本

    在oschina上看到了用c写的红玫瑰, 以前只见过用js写的, 就随手用delphi翻译了c的代码, 效果还不错哈.... 原c作者jokeym贴子 http://www.oschina.net/c ...

  6. POJ1942——Paths on a Grid(组合数学)

    Paths on a Grid DescriptionImagine you are attending your math lesson at school. Once again, you are ...

  7. 【HDOJ】2459 Maximum repetition substring

    后缀数组+RMQ. /* 2459 */ #include <iostream> #include <sstream> #include <string> #inc ...

  8. You must supply a layout_width attribute的错误原因及解决办法

    学习android的过程中,尝试新功能,结果出现了这个一个error: 05-21 15:38:52.745: E/AndroidRuntime(17608): java.lang.RuntimeEx ...

  9. python中的commands模块

    commands模块用于调用shell命令 有3中方法: commands.getstatus()   返回执行状态 commands.getoutput()   返回执行结果 commands.ge ...

  10. poj 2253 Frogger(最短路 floyd)

    题目:http://poj.org/problem?id=2253 题意:给出两只青蛙的坐标A.B,和其他的n-2个坐标,任一两个坐标点间都是双向连通的.显然从A到B存在至少一条的通路,每一条通路的元 ...