[树形DP]JZOJ 5819 大逃杀
分析
也就比餐馆多了一个情况就是经过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); }
在日渐沉没的世界里,我发现了你。