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;

}

 

 

你可能感兴趣的:(host)