题意:
一个游戏的迷宫是一颗树型结构..树上的点代表了房间..每个房间里宝藏..有些房间里有陷阱..现在开始游戏..咱有C条命..若进入了有trap的房间..就会掉一条命..没有命了就Game Over了...可以从这颗树中任意的点开始沿着边走...问能获得的最多宝藏...
题解:
练习赛的时候..用2维来做...果断跪了...这道题用两个维度是无法将所有的状态表示出来的...因为这道题有别于裸求树中某条链的最大价值...从某种程度上来说路径是有向的...就像第一个样例...1可以更新到2..2不能更新到0(因为到了2...拿了宝藏就Game Over了)..但是从0可以更新到2...
可以发现路径有向的情况为路径上有exactly C个trap....而一条合法链上出现C个trap当且仅当其至少有一头(起点 or 终点)为有trap的点...那么状态转化为三维的表示:
dp[node][trap_num][k]...代表以node为一头的链..其陷阱个数为trap_num...链的另一个端点是否为有trap..如此..还是用传统的树形DP来解决了...统计答案的时候保证两头至少有一个为有trap的就行了...
WA了几才过..原因是初始化..因为更新时实际上是要判断是否有值可以更新过来的...而我的dp值初始化为0...导致转移出了些问题....如果省去一些转移判断..dp值的初始化还是定义为负无穷大吧...这些细节一定要注意...
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#define ll long long
#define eps 1e-5
#define oo 1000000007
#define pi acos(-1.0)
#define MAXN 50005
#define MAXM 2000005
using namespace std;
struct node
{
int w,c;
}P[MAXN];
struct LINE
{
int x,y,next;
}line[2*MAXN];
int Lnum,_next[MAXN],dp[MAXN][5][2],C,ans;
void addline(int x,int y)
{
line[++Lnum].next=_next[x],_next[x]=Lnum;
line[Lnum].x=x,line[Lnum].y=y;
}
void dfs(int x,int father)
{
int y,k,i,j;
dp[x][P[x].c][P[x].c]=P[x].w;
for (k=_next[x];k;k=line[k].next)
{
y=line[k].y;
if (y==father) continue;
dfs(y,x);
for (i=0;i<=C;i++)
for (j=0;j<=C-i;j++)
{
ans=max(ans,dp[x][i][0]+dp[y][j][1]);
ans=max(ans,dp[x][i][1]+dp[y][j][0]);
ans=max(ans,dp[x][i][1]+dp[y][j][1]);
if (i+j==C) continue;
ans=max(ans,dp[x][i][0]+dp[y][j][0]);
}
//---------------------------------------------------------------
for (i=0;i<=C;i++)
{
dp[x][i+P[x].c][0]=max(dp[x][i+P[x].c][0],P[x].w+dp[y][i][0]);
dp[x][i+P[x].c][1]=max(dp[x][i+P[x].c][1],P[x].w+dp[y][i][1]);
}
}
return;
}
int main()
{
int T,N,i;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&N,&C);
for (i=0;i<N;i++) scanf("%d%d",&P[i].w,&P[i].c);
memset(_next,0,sizeof(_next));
Lnum=0;
for (i=1;i<N;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addline(x,y),addline(y,x);
}
memset(dp,-0x3f,sizeof(dp));
ans=0;
dfs(0,-1);
printf("%d\n",ans);
}
return 0;
}