zoukankan      html  css  js  c++  java
  • HDOJ 4276 The Ghost Blows Light(树形DP)

    此题很好,很费脑力,还好以前把背包9讲看完了,这次容易理解点

     
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <vector>
    #include <queue>
    using namespace std;
    #define max(a,b)    (((a) > (b)) ? (a) : (b))
    const int INF = 1e9;
    
    struct Node {
        int y, w;
        Node(int _y, int _w) : y(_y), w(_w) { }
    };
    
    vector<Node> map[110];
    int dp[110][510];   // dp[i][j] 从i出发又返回i,最大花费为j时所取得的价值
    int val[110], mark[110];
    
    int bfs(int s, int e)
    {
        int dist[110], f[110];
        for (int i = 0; i < 110; ++i)
            dist[i] = INF;
        f[s] = -1;
        dist[s] = 0;
        queue<int> q;
        q.push(s);
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            for (int i = 0; i < map[u].size(); ++i)
            {
                Node &v = map[u][i];
                if (dist[v.y] > dist[u] + v.w)
                {
                    f[v.y] = u;
                    dist[v.y] = dist[u] + v.w;
                    q.push(v.y);
                }
            }
        }
        for (int i = e; i != -1; i = f[i])
            mark[i] = 1;
        return dist[e];
    }
    
    void dfs(int u, int pre, int mval)
    {
        dp[u][0] = val[u];
        for (int i = 0; i < map[u].size(); ++i)
        {
            int y = map[u][i].y;
            int w = map[u][i].w;
            if (y == pre || mark[y])
                continue;
            dfs(y, u, mval);
    
            for (int j = mval; j >= 0; --j)
                for (int k = 0; k <= j-2*w; ++k)
                    if (dp[u][j-k-2*w] != -1 && dp[y][k] != -1)
                        dp[u][j] = max(dp[u][j], dp[y][k] + dp[u][j-k-2*w]);
        }
    }
    
    int main()
    {
        int n, t;
        while (scanf("%d %d", &n, &t) == 2)
        {
            memset(map, 0, sizeof(map));
            memset(dp, -1, sizeof(dp));
            memset(mark, 0, sizeof(mark));
    
            int a, b, c;
            for (int i = 1; i < n; ++i)
            {
                scanf("%d %d %d", &a, &b, &c);
                map[a].push_back(Node(b, c));
                map[b].push_back(Node(a, c));
            }
            for (int i = 1; i <= n; ++i)
                scanf("%d", &val[i]);
    
            int tt = bfs(1, n);
            if (tt > t)
            {
                printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
                continue;
            }
            for (int i = 1; i <= n; ++i)
                if (mark[i])
                    dfs(i, -1, t - tt);
    
            int dp2[510], tmax = t - tt;
            memset(dp2, -1, sizeof(dp2));
            dp2[0] = 0;
            for (int i = 1; i <= n; ++i)
            {
                if (!mark[i])
                    continue;
                for (int j = tmax; j >= 0; --j)
                {
                    for (int k = 0; k <= j; ++k)
                        if (dp2[j-k] != -1 && dp[i][k] != -1)
                            dp2[j] = max(dp2[j], dp2[j-k] + dp[i][k]);
                        
                }
            }
            int ans = 0;
            for (int i = 0; i <= tmax; ++i)
                if (ans < dp2[i])
                    ans = dp2[i];
            printf("%d\n", ans);
        }
        return 0;
    }

     

    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    允许debian wheezy支持IOS7+的iphone.
    openSUSE 国内镜像摘要
    策略模式总结
    顺序串
    WindowState注意事项
    NLP | 自然语言处理
    Using Autorelease Pool Blocks
    NSAutoreleasePool & thread
    oc语言特性
    oc语言基础整理
  • 原文地址:https://www.cnblogs.com/kedebug/p/2752002.html
Copyright © 2011-2022 走看看