hdu1011

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<fstream>
//#include <sstream>
#include<vector>
using namespace std;
const int MAX=120;
int N,M;
int trooper[MAX];//表示第i个房间拥有的trooper的个数;
int brain[MAX];
int dp[MAX][MAX];
vector<int> adj[MAX];
bool vis[MAX];
void dfs(int root)
{
for(int i=trooper[root];i<=M;i++)
{
dp[root][i]=brain[root];
}
if(vis[root]==false) 
vis[root]=true;
else return ;

int num=adj[root].size();
//cout<<"continue endl"<<endl;
for(int j=0;j<num;j++)
{
//cout<<"j="<<j<<endl;
//cout<<"hello1"<<endl;
int v=adj[root][j];
//cout<<"v="<<v<<endl;
if(vis[v])
{
//cout<<"continue"<<endl;
continue;
}

   //if(v==pre) continue;
//cout<<"hello"<<endl;
//dfs(v,root);
dfs(v);
//cout<<"arrive="<<root<<endl;


for(int y=M;y>=trooper[root];y--)
{
for(int yo=1;yo<=y-trooper[root];yo++)//之前的程序for(int yo=1;yo<=M;yo++)这是个致命的错误,本身不应该到M点,不然就会上层循环矛盾的地方。
//因为本身的士兵就M个,结果上层用了M个,这层用M个,这完全是不行的。后面又改成了,M-trooper[root],
//这个也是原来的道理是一样的。最后用y-trooper[root],是因为当前的房间用掉了trooper【root】个,所以不能算在内
{
//cout<<"arrive="<<"yyo"<<endl;
if(dp[root][y]<dp[root][y-yo]+dp[v][yo])
{

dp[root][y]=dp[root][y-yo]+dp[v][yo];
//printf("dp[%d][%d]=dp[%d][%d]+dp[%d][%d]=%d\n",root,y,root,y-yo,v,yo,dp[root][y]=dp[root][y-yo]+dp[v][yo]);
//上面的注释可以做调试用,在运行程序的时候,一直没有发现错误,然后通过输出数据,结果是死循环的问题,
//然后通过看双循环的代码,发现确实在里面是死循环了,而且这种错误会在运行的时候出现错误,不易发现。
}
}
}


}
//cout<<"continue endl endl"<<endl;
return ;


}


int main()
{
//ifstream ifile("D://ACM/hdu1011.txt");
//ifile.open("D:\ACM\hdu1011.txt");
/*
if(!ifile) {
cerr<<"error."<<endl;
return -1;
}
*/

while(cin>>N>>M)
{
if(N==-1&&M==-1) break;

//if(M==0) {cout<<"0\n";continue;}之前花了很长时间一直没有发现错误,结果是自己细节方面疏忽了。之前以为M==0
//就可以了,结果忘记了,接下去还要按照N的要求,输入N个和N-1个组的数据。这个对于我来说值得给自己一个嘴巴。
//太不细心了。

memset(brain,0,sizeof(brain));
memset(trooper,0,sizeof(trooper));
memset(vis,false,sizeof(vis));
memset(dp,0,sizeof(dp));
for(int ii=0;ii<=N;ii++)
{
adj[ii].clear();
}
for(int i=1;i<=N;i++)
{
//ifile>>trooper[i]>>brain[i];
cin>>trooper[i]>>brain[i];
trooper[i]=(trooper[i]+19)/20;
}
for(int j=1;j<N;j++)
{
int a,b;
//ifile>>a>>b;
cin>>a>>b;
adj[a].push_back(b);
adj[b].push_back(a);
}


if(M==0) {cout<<"0\n";continue;}
dfs(1);//,-1);
cout<<dp[1][M]<<endl;


}
//ifile.close();
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值