本文主要是介绍Hdu1011 Starship Troopers -- 树形背包,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
/*
题意:星河战队要去完成任务:用有限的战士去俘获尽可能多的首脑。
条件和注意:1:一颗树(没有重边,没有环,没有孤立点),表示敌军的基地地图
2:一个战士可以战胜20个敌人,保证战士不重复战斗,不走回路。
3:要想抓到首脑,必须要有战士进入房间。
分析:树上跑背包。
*/
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cmath>
using namespace std;
struct room
{
int need;//房间里需要的战士数
int per;//抓到brain的概率
}m[105];
vector<int> r[110];
int so[110][110],v[110],s;
int max(int x,int y)
{return x>y?x:y;}
void dfs(int x)
{
v[x] = 1;
int u;
for(int i=s;i>=m[x].need;i--)
so[x][i] = m[x].per;
for (int i = 0; i < r[x].size(); i++)
{
u = r[x][i];
if(!v[u])
{
dfs(u);
for (int j = s; j >= m[x].need; j--)
{
for (int k = 1; k <= j-m[x].need; k++)
{//树上跑背包,转移方程
so[x][j] = max(so[x][j],so[x][j-k]+so[u][k]);
}
}
}
}
}
int main()
{
int M,x,a,b;
while(scanf("%d %d",&M,&s)!=EOF)
{
if(M==-1 && s==-1) break;
memset(v,0,sizeof(v));
memset(so,0,sizeof(so));
for (int i = 1; i <= M; i++)
{
r[i].clear();
}
for (int i = 1; i <= M; i++)
{
scanf("%d %d",&x,&m[i].per);
m[i].need = ceil(x/20.0);
}
for (int i = 1; i < M; i++)
{
scanf("%d %d",&a,&b);
r[a].push_back(b);//存边
r[b].push_back(a);
}
if(s==0)
{
printf("0\n");
continue;
}
dfs(1);
printf("%d\n",so[1][s]);//从一号房间进入s个战士,最大值。
}
return 0;
}
这篇关于Hdu1011 Starship Troopers -- 树形背包的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!