[树形DP]JZOJ 5819 大逃杀

Description

自从 Y 君退役之后,她就迷上了吃鸡,于是她决定出一道吃鸡的题。
Y 君将地图上的所有地点标号为 1 到 n,地图中有 n − 1 条双向道路连接这些点,通过一条 双向道路需要一定时间,保证从任意一个点可以通过道路到达地图上的所有点。
有些点上可能有资源,Y 君到达一个有资源的点后,可以选择获取资源来使自己的武力值增 加 wi,也可以选择不获取资源。如果 Y 君获取了一个点上的资源,这个点上的资源就会消失,获 取资源不需要时间。
有些点上可能有敌人,Y 君到达一个有敌人的点后,必须花费 ti 秒伏地与敌人周旋,并最终 将敌人消灭。如果 Y 君消灭了一个点上的敌人,这个点上的敌人就会消失。Y 君不能无视敌人继 续前进,因为这样会被敌人攻击。
如果一个点上既有资源又有敌人,Y 君必须先消灭敌人之后才能获取资源,否则就会被敌人 突袭。
游戏开始时,Y 君可以空降到任意一个点上,接下来,她有 T 秒进行行动,T 秒后她就必须 前往中心区域送快递。Y 君希望她前往中心区域送快递时,武力值尽可能大,请你帮助 Y 君设计 路线,以满足她的要求。你只需输出 T 秒后 Y 君的武力值。 
 

Input

第一行由单个空格隔开的两个正整数 n, T,代表点数和时间。
第二行 n 个由单个空格隔开的非负整数代表 wi,如果 wi = 0 代表该点没有武器,
第三行 n 个由单个空格隔开的非负整数代表 ti,如果 ti = 0 代表该点没有敌人。
接下来 n − 1 行每行由单个空格隔开的 3 个非负整数 a, b, c 代表连接 a 和 b 的双向道路,通 过这条道路需要 c 秒。 

Output

输出一行一个整数代表 T 秒后 Y 君的武力值。
 

Sample Input

17 54
5 5 1 1 1 25 1 10 15 3 6 6 66 4 4 4 4
0 1 3 0 0 0 1 3 2 0 6 7 54 0 0 0 0
1 8 3
2 8 3
8 7 7
7 13 0
7 14 0
15 14 2 
16 14 3
17 14 5
7 9 4
9 10 25
10 11 0
10 12 0
7 6 20
3 6 3
3 4 3
3 5 3 

Sample Output

68
 

Data Constraint

分析

也就比餐馆多了一个情况就是经过i但是不停留在i的

然后乱搞一波DP,预处理等等就行

具体方程看代码

#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
const int N=301;
struct Edge {
    int u,v,t,nx;
}g[2*N];
int cnt,list[N];
int w[N],t[N];
long long f[N][N][3];
int n,T;
long long ans;

void Max(long long &a,long long b) {if (a<b) a=b;}

void Add(int u,int v,int t) {g[++cnt].u=u;g[cnt].v=v;g[cnt].t=t;g[cnt].nx=list[u];list[u]=cnt;}

void Dfs(int u,int fa) {
    for (int i=0;i<=T;i++) f[u][i][0]=f[u][i][1]=f[u][i][2]=i>=t[u]?w[u]:-2147483647;
    for (int i=list[u];i;i=g[i].nx)
    if (g[i].v!=fa) {
        Dfs(g[i].v,u);
        long long cpy[N][3];
        memcpy(cpy,f[u],sizeof cpy);
        for (int j=T;j>=0;j--)
        for (int k=0;k<=T;k++) {
            if (j-k-2*g[i].t>=0)
            Max(f[u][j][0],cpy[j-k-2*g[i].t][0]+f[g[i].v][k][0]),
            Max(f[u][j][1],cpy[j-k-2*g[i].t][1]+f[g[i].v][k][0]),
            Max(f[u][j][2],cpy[j-k-2*g[i].t][2]+f[g[i].v][k][0]),
            Max(f[u][j][2],cpy[j-k-2*g[i].t][0]+f[g[i].v][k][2]);
            if (j-k-g[i].t>=0)
            Max(f[u][j][1],cpy[j-k-g[i].t][0]+f[g[i].v][k][1]),
            Max(f[u][j][2],cpy[j-k-g[i].t][1]+f[g[i].v][k][1]);
        }
    }
    Max(ans,max(f[u][T][0],max(f[u][T][1],f[u][T][2])));
}

int main() {
    freopen("toyuq.in","r",stdin);
    freopen("toyuq.out","w",stdout);
    scanf("%d%d",&n,&T);
    for (int i=1;i<=n;i++) scanf("%d",&w[i]);
    for (int i=1;i<=n;i++) scanf("%d",&t[i]);
    for (int i=1;i<n;i++) {
        int u,v,t;
        scanf("%d%d%d",&u,&v,&t);
        Add(u,v,t);Add(v,u,t);
    }
    Dfs(1,0);
    printf("%lld",ans);
    fclose(stdin);fclose(stdout);
}
View Code

 

posted @ 2018-08-15 20:48  Vagari  阅读(274)  评论(0编辑  收藏  举报