1774:大逃杀
1774:大逃杀
时间限制: 1000 ms 内存限制: 262144 KB
提交数: 49 通过数: 19
【题目描述】
将地图上的所有地点标号为1到n,地图中有n-1
条双向道路连接这些点,通过一条双向道路需要一定时间,保证从任意一个点可以通过道路到达地图上的所有点。
有些点上可能有资源,到达一个有资源的点后,可以获取资源来增加 wi的武力值。
资源被获取后就会消失,获取资源不需要时间。可选择不获取资源。
有些点上可能有敌人,到达一个有敌人的点后,必须花费ti秒与敌人周旋,并将敌人消灭。敌人被消灭后就会消失。不能无视敌人。
如果一个点上既有资源又有敌人,必须先消灭敌人才能获取资源。
游戏开始时Y君可以空降到任意一个点上,接下来,有T秒时间行动,Y君希望游戏结束时,武力值尽可能大。
【输入】
第一行由单个空格隔开的两个正整数 n,T,代表点数和时间。
第二行n个由单个空格隔开的非负整数代表 wi,如果wi=0表示该点没有资源。
第三行n个由单个空格隔开的非负整数代表 ti,如果ti=0代表该点没有敌人。
接下来n-1行每行由单个空格隔开的3个非负整数a,b,c表示连接a和b的双向道路,通过这条道路需要c秒。
【输出】
输出一行一个整数代表T秒后Y君的武力值。
【输入样例】
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
【输出样例】
68
【提示】
【数据规模】
对于100%的数据,n,T≤300,0≤wi,ti,c≤106,1≤a,b≤n。
【题解】
因为起点不确定,所以定义三种状态f,g,h[i][j]分别表示在i子树内用了j的时间,f:从i出发,去了子树内在回到i最大收益,g:从i出发,到达子树内任意节点,h从子树内出发,经过i到达子树内任一节点最大收益。根据子树内信息依次转移即可。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=305;
int f[N][N],g[N][N],h[N][N],last[N],size,w[N],t[N],n,T,ans;
struct pigu
{
int dao,ne,quan;
}a[N<<1];
inline void lingjiebiao(int x,int y,int z)
{
a[++size].dao=y;
a[size].quan=z;
a[size].ne=last[x];
last[x]=size;
}
//f表示下去了回来,g表示下去了不回来,h表示从下头来
inline void dfs(int now,int fa)
{
if(t[now]>T) return;
for(int i=last[now];i;i=a[i].ne)
{
if(a[i].dao==fa) continue;
dfs(a[i].dao,now);
for(int j=T;j>=t[now];j--)
{
for(int k=j-a[i].quan;k>=t[now];k--)
{
int h1=f[now][k],h2=g[now][k],h3=h[now][k];//k表示之前用了好多时间了。
int shen=j-k-a[i].quan;
if(shen>=t[a[i].dao])
{
g[now][j]=max(g[now][j],h1+g[a[i].dao][shen]);
h[now][j]=max(h[now][j],h2+g[a[i].dao][shen]);
}
shen-=a[i].quan;
if(shen>=t[a[i].dao])
{
g[now][j]=max(g[now][j],h2+f[a[i].dao][shen]);
f[now][j]=max(f[now][j],f[a[i].dao][shen]+h1);
h[now][j]=max(h[now][j],h3+f[a[i].dao][shen]);
h[now][j]=max(h[now][j],h[a[i].dao][shen]+h1);
}
}
ans=max(ans,h[now][j]);
}
}
}
int main()
{
cin>>n>>T;
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=n;i++)
{
cin>>t[i];
if(t[i]<=T)
f[i][t[i]]=g[i][t[i]]=h[i][t[i]]=w[i];
}
for(int i=1,x,y,z;i<=n-1;i++)
{
cin>>x>>y>>z;
lingjiebiao(x,y,z);
lingjiebiao(y,x,z);
}
dfs(1,0);
cout<<ans;
}