hdu 1011 Starship Troopers_나무

1813 단어 oop
제목 링크
제목: 나무 한 그루(뿌리 노드에서 출발해야 함)를 드리겠습니다. 노드마다 버그와value가 있습니다. 당신은 m명의 기사가 있습니다. 기사마다 20개의 버그를 처치할 수 있습니다. 이 노드의 모든 버그를 처치해야 이 노드의value를 얻을 수 있습니다. 최대value가 얼마인지 물어보세요.
사고방식: 전형적인 가방 dp, dp[n][m]=max(dp[n][m-x]+value, dp[n][m])
#include<iostream>
#include<cstdio>
using namespace std;
#define N 110
#define INF 999999999
struct node
{
	int v,next;
}edge[N<<1];
int adj[N],vis[N],room[N][2],dp[N][N],edgeNum;
int max(int a,int b){return a>b?a:b;}
void AddEdge(int u,int v)
{
	edge[edgeNum].v=v,edge[edgeNum].next=adj[u],adj[u]=edgeNum++;
	edge[edgeNum].v=u,edge[edgeNum].next=adj[v],adj[v]=edgeNum++;
}
void init()
{
	memset(vis,0,sizeof(vis));
	memset(adj,-1,sizeof(adj));
	memset(dp,0,sizeof(dp));
	edgeNum=0;
}
void dfs(int u,int m)
{
	int num=room[u][0]/20,i,j,k;
	if(room[u][0]%20)//bug                 bug 
		num++;
	vis[u]=1;
	for(i=num;i<=m;i++)
		dp[u][i]=room[u][1];//         
	for(i=adj[u];i!=-1;i=edge[i].next)
	{
		int v=edge[i].v;
		if(!vis[v])
		{
			dfs(v,m);
			for(j=m;j>=num;j--)
			{
				for(k=1;j+k<=m;k++)
					if(dp[v][k])
						dp[u][k+j]=max(dp[u][k+j],dp[u][j]+dp[v][k]);//        
			}
		}
	}


}
int main()
{
	int n,m;
	int i,u,v;
	while(scanf("%d%d",&n,&m))
	{
		if(n==-1&&m==-1)
			break;
		init();
		for(i=1;i<=n;i++)
			scanf("%d%d",&room[i][0],&room[i][1]);
		for(i=1;i<n;i++)
		{
			scanf("%d%d",&u,&v);
			AddEdge(u,v);//   
		}
		if(m==0)//     
		{
			printf("0
"); continue; } dfs(1,m);// 1 printf("%d
",dp[1][m]); } return 0; }

좋은 웹페이지 즐겨찾기