您的位置:首页 > 其它

糖果

2016-07-19 09:28 211 查看
题目描述

万圣节那天,小Q想去邻居要糖果,玩下“Trick or Treat”。小Q家和邻居家够成一棵树,即邻居间可以相互到达,并且只有一种方案。小Q的妈妈将在m分钟后回来,如果发现小Q不在家会很生气。小Q希望获得最多的糖果,并且在m分钟内回到家中。现在告诉你每条路要花的时间,并假设小Q到了邻居家后就能拿到糖果,不需要花时间,当然每个邻居只会给一次糖果,以后经过的时候,就不再给了。请你帮她算算,她最多能拿到多少糖果。

输入

输入数据一行,一个正数n表示小Q所在的敌方有多少户人家。

接下一行n个数,表示每户人家给她的糖数vali。

接下来n-1,每行三个数,a, b, c,表示通过连接编号为a, b的人家的路要花费c分钟的时间,1<=a, b<=n。

最后一行,两个整数k, m,k表示小Q家的编号(小Q也能从自己家获得糖果),m表示妈妈m分钟后回家。

输出

输出一个整数表示小Q能获得最多糖果数量。

样例输入

2

1 3

2 1 1

2 1

样例输出

3

输入:

2

3 3

1 2 1

2 2

输出:

6

样例一解释:小Q只能获得自己家的糖果,不能在m分钟去其他的地方再赶回来。

样例二解释:小Q能获得自己家的糖果和编号为1邻居家的糖果,并恰好在m分钟赶回家中。

对于30%的数据1<=n<=10;

对于100%的数据,1<=n<=100,1<=m<=200 ,0<=vali <=1000,1<=c<=10;

树形背包

f[i][j]表示以i为出发点用了j时间,累计的最大值

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,x,y,z,tot,ans,start;
int f[105][205];
int a[105],head[105],Next[205],to[205],cost[205];
void add(int x,int y,int z)
{
tot++;
Next[tot]=head[x];
to[tot]=y;
cost[tot]=z;
head[x]=tot;
}
void dfs(int k,int pre)
{
f[k][0]=a[k];
for(int i=head[k];i!=-1;i=Next[i])
if(to[i]!=pre)
{
dfs(to[i],k);
for(int j=m;j>=cost[i];j--)
for(int x=0;x<=j;x++)
if(j-x>=cost[i]*2)
f[k][j]=max(f[k][j],f[k][x]+f[to[i]][j-x-cost[i]*2]);
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) head[i]=-1;
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
cin>>start>>m;
dfs(start,-1);
ans=0;
for(int i=0;i<=m;i++) ans=max(ans,f[start][i]);
cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: