zoukankan      html  css  js  c++  java
  • HDU 4616 Game (搜索)、(树形dp)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4616


    这道题目数据可能比较弱,搜索都可以AC,但是不敢写,哎……


    搜索AC代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <list>
    #include <deque>
    #include <queue>
    #include <iterator>
    #include <stack>
    #include <map>
    #include <set>
    #include <algorithm>
    #include <cctype>
    #include <ctime>
    #pragma comment(linker, "/STACK:16777216")
    using namespace std;
    
    typedef __int64 LL;
    const int N=50005;
    const int M=55555555;
    const int INF=0x3f3f3f3f;
    const double PI=acos(-1.0);
    
    vector<int>q[N];
    int xh[N],w[N];
    int n,c,sm;
    bool vis[N];
    
    struct love
    {
        int i,sum;
        int cc;
    }r,e,my[M];
    
    void BFS(int s)
    {
        memset(vis,0,sizeof(vis));
        vis[s]=1;
        vector<int>::iterator it;
        r.i=s;
        r.sum=xh[s];    sm=max(sm,r.sum);
        r.cc=c-w[s];
        if(r.cc==0)
            return ;
        int he=0,ta=0;
        my[ta++]=r;
        while(he!=ta)
        {
            e=my[he++];
            if(he==M)
                he=0;
            for(it=q[e.i].begin();it!=q[e.i].end();it++)
            {
                r=e;
                int k=*it;
                if(vis[k])  continue;
                vis[k]=1;
                r.i=k;
                r.sum+=xh[k];   sm=max(sm,r.sum);
                r.cc-=w[k];
                if(r.cc>0)
                {
                    my[ta++]=r;
                    if(ta==M)
                        ta=0;
                }
            }
        }
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&c);
            for(int i=0;i<n;i++)
            {
                scanf("%d%d",&xh[i],&w[i]);
            }
            for(int i=0;i<=n;i++)
                q[i].clear();
            for(int i=0;i<n-1;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                q[a].push_back(b);
                q[b].push_back(a);
            }
            int Max=-1;
            for(int i=0;i<n;i++)
            {
                sm=0;
                if(q[i].size()==1)
                    BFS(i);
                if(Max<sm)
                    Max=sm;
            }
            cout<<Max<<endl;
        }
        return 0;
    }
    


    树形DP代码:

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    using namespace std;
    #define N 50500
    int trap[N],val[N],n,C,vis[N],ans;
    int dp[N][5][2];
    vector<int>vec[N];
    
    void DP(int u)
    {
        vis[u]=1;
        dp[u][trap[u]][0]=dp[u][trap[u]][1]=val[u];
        int v;
        for(int i=0;i<vec[u].size();++i)
        {
            v=vec[u][i];
            if(vis[v]) continue;
            DP(v);
            for(int j=0;j<=C;++j)
                for(int k=0;j+k<=C;++k)
            {
                if(j!=C) // j=C的时候已经停止了,不会再往子节点跑了
                    ans=max(ans,dp[u][j][0]+dp[v][k][1]);
                if(k!=C) // 同理
                    ans=max(ans,dp[u][j][1]+dp[v][k][0]);
                if(j+k<C) // 0表示从子树方向往根节点跑,子树可能是非陷阱的点,
                    //假如j+k==C,题意要求到达C要停止,但按dp[v][k][0]记录的,还会继续跑,所以不行
                    ans=max(ans,dp[u][j][0]+dp[v][k][0]);
                //if(j+k<C)
                    //ans=max(ans,dp[u][j][1]+dp[v][k][1]); 
            }
            for(int j=0;j+trap[u]<=C;++j)
                dp[u][j+trap[u]][0]=max(dp[u][j+trap[u]][0],dp[v][j][0]+val[u]);
            for(int j=1;j+trap[u]<=C;++j) // 1表示从根节点往下走的,1->0是不可取的,因为算上1后,已经满C了,就不会再走了,所以不能更新
                dp[u][j+trap[u]][1]=max(dp[u][j+trap[u]][1],dp[v][j][1]+val[u]);
        }
    }
    int main ()
    {
        int ncase;scanf("%d",&ncase);
        while(ncase--)
        {
            scanf("%d%d",&n,&C);
            for(int i=0;i<n;++i)
                vec[i].clear();
            memset(vis,0,sizeof(vis));
            memset(dp,0,sizeof(dp));
            ans=0;
            for(int i=0;i<n;++i)
                scanf("%d%d",&val[i],&trap[i]);
            int u,v;
            for(int i=1;i<n;++i)
            {
                scanf("%d%d",&u,&v);
                vec[u].push_back(v);
                vec[v].push_back(u);
            }
            DP(0);
            printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    mysql字符集设置
    mysql解压版服务启动方式
    html的表格边框为什么会这么粗?
    通过js获取tinymce4.x的值
    bzoj 3083 树链剖分
    bzoj 1143 二分图最大独立集
    bzoj 2303 并查集
    可持久化数据结构讲解
    bzoj 1072 状压DP
    bzoj 2741 可持久化trie
  • 原文地址:https://www.cnblogs.com/riskyer/p/3281299.html
Copyright © 2011-2022 走看看