HDU 3660 Alice and Bob's Trip【树形DP】

题意: Alice 和 Bob在一颗树上轮流走,知道了每条边的长度,Alice想走的权值和尽量小,Bob想走尽量大,同时所走的权值和必须在[L, R]这个给定的区间内,

          Bob先走,问Bob 能得走的最大的权值和是多少?  如果还能走,Alice就不能停下来。
分析: dp[r] 表示到节点 r 的最优值,从叶子递归,Alice选每次最小走,Bob选最大走,d[u]表示从跟到节点u的距离,

          d[u]+dp[t]+cost(u, t) 必须在[L, R]之间才转移

#include<stdio.h>
#include<string.h>
#define INF 0x1f1f1f1f
#define max(a,b)(a)>(b)?(a):(b)
#define min(a,b)(a)<(b)?(a):(b)
#define clr(x)memset(x,0,sizeof(x))
#define maxn 500005
struct node
{
    int to,next,w;
}e[10000000];
int tot;
int head[maxn];
void add(int s,int t,int wi)
{
    e[tot].to=t;
    e[tot].w=wi;
    e[tot].next=head[s];
    head[s]=tot++;
}
int n,L,R;
int dp[maxn];
int d[maxn];
void dfs(int r,int p)
{
    if(d[r]>R)
    {
        dp[r]=0;
        return;
    }
    dp[r]=p?-1:INF;
    int flag=1,i,k;
    for(i=head[r];i;i=e[i].next)
    {
        flag=0;
        k=e[i].to;
        d[k]=d[r]+e[i].w;
        dfs(k,!p);
        if(dp[k]==-1||dp[k]==INF)
            continue;
        int tmp=d[r]+dp[k]+e[i].w;
        if(tmp>=L&&tmp<=R)
        {
            if(p)
                dp[r]=max(dp[r],dp[k]+e[i].w);
            else 
                dp[r]=min(dp[r],dp[k]+e[i].w);
        }
    }
    if(flag)
        dp[r]=0;
}
int main()
{
    int i;
    while(scanf("%d%d%d",&n,&L,&R)!=EOF)
    {
        tot=1;
        clr(head);
        int a,b,c;
        for(i=1;i<n;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        clr(d);
        dfs(0,1);
        if(dp[0]>=L&&dp[0]<=R)
            printf("%d\n",dp[0]);
        else printf("Oh,my god!\n");
    }
    return 0;
}

 

posted @ 2012-09-13 23:48  'wind  阅读(468)  评论(0编辑  收藏  举报