现在的位置: 首页 > 综合 > 正文

HDU 4276 The Ghost Blows Light 树形dp

2018年04月25日 ⁄ 综合 ⁄ 共 1758字 ⁄ 字号 评论关闭

题意:有n(n<=100)个点的树,每个点有固定的val值,走每条边需要花费固定的时间,问Hu Bayi能否从1在给定的时间范围内走到n(n点为出口),
         如果不能输出"Human beings die in pursuit of wealth, and birds die in pursuit of food!",如果能输出在所经过的路径上能得到的最大val和。
题解:树形dp,首先DFS得出从1->n路径上的权值和tot,并将路径上的权值置0,这样能够保证从1->n的路径始终是通的,然后进行树形dp+01背包即可。

Sure原创,转载请注明出处。

#include <iostream>
#include <cstdio>
#include <memory.h>
#define MAX(a , b) ((a) > (b) ? (a) : (b))
using namespace std;
const int maxn = 102;
const int maxm = 502;
struct node
{
    int v,w;
    int next;
}edge[maxn << 1];
int head[maxn],val[maxn],dp[maxn][maxm];
bool vis[maxn];
int m,n,idx,tot;

void init()
{
    memset(head,-1,sizeof(head));
    memset(vis,false,sizeof(vis));
    idx = tot = 0;
    return;
}

void addedge(int u,int v,int w)
{
    edge[idx].v = v;
    edge[idx].w = w;
    edge[idx].next = head[u];
    head[u] = idx++;

    edge[idx].v = u;
    edge[idx].w = w;
    edge[idx].next = head[v];
    head[v] = idx++;
    return;
}

void read()
{
    int u,v,w;
    for(int i=1;i<n;i++)
    {
        scanf("%d %d %d",&u,&v,&w);
        addedge(u,v,w);
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&val[i]);
    }
    return;
}

void DFS(int st,int pre)
{
    if(st == n)
    {
        vis[st] = true;
    }
    for(int i=head[st];i != -1;i=edge[i].next)
    {
        if(edge[i].v == pre) continue;
        DFS(edge[i].v , st);
        if(vis[edge[i].v])
        {
            vis[st] = true;
            tot += edge[i].w;
            edge[i].w = edge[i^1].w = 0;
        }
    }
    return;
}

void dfs(int st,int pre)
{
    int v = -1;
    for(int i=head[st];i != -1;i=edge[i].next)
    {
        if(edge[i].v == pre) continue;
        if(vis[edge[i].v])
        {
            v = edge[i].v;
            continue;
        }
        dfs(edge[i].v , st);
        for(int j=m;j>=edge[i].w * 2;j--)
        {
            for(int k=0;k + edge[i].w * 2 <= j;k++)
            {
                dp[st][j] = MAX(dp[st][j] , dp[st][j-edge[i].w * 2 - k] + dp[edge[i].v][k]);
            }
        }
    }
    if(v != -1)
    {
        for(int i=0;i<=m;i++)
        {
            dp[v][i] = dp[st][i] + val[v];
        }
        dfs(v , st);
    }
    return;
}

void solve()
{
    DFS(1,0);
    if(tot > m)
    {
        puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!");
        return;
    }
    m -= tot;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=m;j++)
        {
            dp[i][j] = val[i];
        }
    }
    dfs(1,0);
    printf("%d\n",dp[n][m]);
    return;
}

int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        init();
        read();
        solve();
    }
    return 0;
}

抱歉!评论已关闭.