zoukankan      html  css  js  c++  java
  • hdu 3660 Alice and Bob's Trip(树形DP)

    Alice and Bob's Trip

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2643    Accepted Submission(s): 708

    Problem Description
    Alice and Bob are going on a trip. Alice is a lazy girl who wants to minimize the total travelling distance, while Bob as an active boy wants to maximize it. At the same time, they cannot let the value to be less than a given integer L since that will make them miss too much pleasure, and they cannot let the value to be greater than a given integer R since they don't want to get too exhausted.
    The city they are visiting has n spots and the spots are connected by directed edges. The spots are connected in such a way that they form a tree and the root will always be at spot 0. They take turns to select which edge to go. Both of them choose optimally. Bob will go first.
     
    Input
    There are multiple test cases. For every test case, the first line has three integers, n, L and R (1<=n<=500000, 0<=L, R<=1000000000). The next n-1 lines each has three integers a, b and c, indicating that there is an edge going from spot a to spot b with length c (1<=c<=1000). The spots are labeled from 0 to n-1.
    There is a blank line after each test case.
    Proceed to the end of file.
     
    Output
    If the total distance is not within the range [L, R], print "Oh, my god!" on a single line. Otherwise, print the most value Bob can get.
     
    Sample Input
    3 2 4 0 1 1 0 2 5 7 2 8 0 1 1 0 2 1 1 3 1 1 4 10 2 5 1 2 6 5 7 4 8 0 1 1 0 2 1 1 3 1 1 4 2 2 5 1 2 6 5 4 2 6 0 1 1 1 2 1 1 3 5
     
    Sample Output
    Oh, my god! 2 6 2
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:   3669  3668  3667  3666  3662 
     

    题意:

    A和B要去旅游。这有N个城市。而这些的城市的道路为一颗树。且边有向。A和B从0出发一起去旅游。A很懒想尽量少走路。B很有活力想尽量多走路但是无论怎么选择他们走的总路程都必须满足在[L,R]的范围内。所以他们交替选择走哪条路。开始由B选。然后问你在都采用最优策略的情况下。B最多能走多少路。

    思路:

    算是比较水的树形DP吧。由于道路是一颗树所以很多东西是可以确定的。比如根到这个节点的距离。和该结点由谁选择。所以就很简单了。用dp[i]表示经过i号结点B所能获得的最大价值。为-1时表示不能经过该结点。比赛时太困了大脑完全就不转了。还好队友解决了。下来一下下就解决了。不过比赛时要优化输入才过不然要TLE。在外面用C++交就不会超时了。

    详细见代码:

    #include<algorithm>
    #include<iostream>
    #include<string.h>
    #include<sstream>
    #include<stdio.h>
    #include<math.h>
    #include<vector>
    #include<string>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int maxn=500010;
    int cnt,n,L,R;
    int dp[maxn];
    struct node
    {
        int v;
        int val;
        node *next;
    } edge[maxn],*head[maxn];
    void adde(int u,int v,int w)
    {
        edge[cnt].v=v;
        edge[cnt].val=w;
        edge[cnt].next=head[u];
        head[u]=&edge[cnt++];
    }
    void dfs(int np,int d,bool ok)//ok=1表示B选0表示A选
    {
        node *p;
        if(head[np]==NULL)//到叶子结点时判断可行性。
        {
            if(d>=L&&d<=R)
                dp[np]=d;
            else
                dp[np]=-1;
            return ;
        }
        for(p=head[np];p!=NULL;p=p->next)//只有先处理完儿子才能确定自己
            dfs(p->v,d+p->val,ok^1);
        if(ok)//初始化
            dp[np]=-1;
        else
            dp[np]=INF;
        for(p=head[np];p!=NULL;p=p->next)
        {
            if(ok)
                dp[np]=max(dp[np],dp[p->v]);
            else if(dp[p->v]!=-1)
                dp[np]=min(dp[np],dp[p->v]);
        }
        if(dp[np]==INF)
            dp[np]=-1;
        //printf("np %d  %d
    ",np,dp[np]);
    }
    inline int getint()//优化输入
    {
        char ch=getchar();
        int ans= 0;
        while(ch<'0'||ch>'9')
            ch=getchar();
        do
        {
            ans=ans*10+ch-'0';
            ch=getchar();
        }while(ch>='0'&&ch<='9');
        return ans;
    }
    int main()
    {
        int i,u,v,w;
    
        while(~scanf("%d%d%d",&n,&L,&R))
        {
            cnt=0;
            memset(head,0,sizeof head);
            for(i=1;i<n;i++)
            {
                //scanf("%d%d%d",&u,&v,&w);//优化前1765ms。优化后781ms。所以大型输入时最好还是优化下
                u=getint();
                v=getint();
                w=getint();
                adde(u,v,w);
            }
            dfs(0,0,1);
            if(dp[0]>=0)
                printf("%d
    ",dp[0]);
            else
                printf("Oh, my god!
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    怎样去阅读一份php源代码
    Cloudera Hadoop 4系列实战课程(电商业日志流量分析项目)
    ORACLE系列之SQL从入门到精通(全面把控数据库基础)
    jQuery2.0应用开发:SSH框架整合jQuery2.0实战OA办公自动化
    Unity3D游戏引擎实战开发从入门到精通
    中国移动:物联网项目实战开发企业级应用(ssp框架应用、EXTJS4.2、GoogleMap、JPA)
    基于OpenLayers实战地理信息系统(离线地图,通过基站转经纬度,Quartz深入,轨迹实战)
    Android自动化测试从入门到精通
    博客从新开张啦!
    python scrapy版 极客学院爬虫V2
  • 原文地址:https://www.cnblogs.com/pangblog/p/3402486.html
Copyright © 2011-2022 走看看