hdu3660

/*
分析:
    简单的tree dp,难点是理解题意。。。
    从下往上dp,如果是奇数步,就记录这个点往下可以得到的
在[L,R]内的最大的dis;如果是偶数步,就相反。

                                                             2013-06-26
*/





#include"iostream"
#include"cstdio"
#include"cstring"
using namespace std;
const int N=500005;

int n,L,R,dp[N],flag[N];
struct Edge{
	int v,len,next;
}edge[N];
int tot,head[N];

void dfs(int k,int step,int dis)
{
	if(head[k]==-1)
	{
		dp[k]=0;
		if(L<=dis && dis<=R)	flag[k]=1;
		return ;
	}
	int j,v;
	int min=1234567890,max=-1;
	for(j=head[k];j!=-1;j=edge[j].next)
	{
		v=edge[j].v;
		dfs(v,step+1,dis+edge[j].len);
		if(!flag[v])	continue;
		flag[k]=1;
		if(step%2 && dp[v]+edge[j].len<min)		min=dp[v]+edge[j].len;
		if(step%2==0 && max<dp[v]+edge[j].len)	max=dp[v]+edge[j].len;
	}
	if(step%2)	dp[k]=min;
	else		dp[k]=max;
}
int main()
{
	int i;
	int a,b,c;
	while(scanf("%d%d%d",&n,&L,&R)!=-1)
	{
		tot=0;
		memset(head,-1,sizeof(head));
		for(i=1;i<n;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			edge[tot].v=b;edge[tot].len=c;edge[tot].next=head[a];head[a]=tot++;
		}
		memset(flag,0,sizeof(flag));
		dfs(0,0,0);
		if(dp[0]==-1)	printf("Oh, my god!\n");
		else			printf("%d\n",dp[0]);
	}
	return 0;
}


你可能感兴趣的:(hdu3660)