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

hdu 4276 树形dp + 最短路

2019年02月20日 ⁄ 综合 ⁄ 共 1383字 ⁄ 字号 评论关闭

n个点各有权值val [ i ], 总时间为T,n-1条双向边,u->v,从u走到v 花费为w, 求在花费不超过T的情况下,能获得的经过的各点权值之和最大。

分析:首先预处理出一条从点1 ~ N的最短路, 那么最优路径的主干一定是经过该最短路的。然后是否走其他的点取决于是否有多出的时间(很显然。)。而且经过最短路之外的点的话,那些点要么不走要么走且只走两次(来回)。

所以先预处理出一条最短路之后,最短路上的点权值改为0,然后用树形dp解决是否要取旁边的点。设dp [ u ][ j ]为走到 u 时花费为 j ,那么

dp[u][j] = max(dp[u][j], dp[v][k] + dp[u][j - weit - k]);

完整代码如下:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>

#define N 105

using namespace std;

int a[N];

struct node{
    int to, nxt, cost;
}edge[N * 3];

int head[N];

int dp[N][N * 5];

int cnt;
int n, t;
int tt;

void init()
{
    cnt = 0;
    memset(head, -1, sizeof(head));
}

void addedge(int u, int v, int w)
{
    edge[cnt].to = v;
    edge[cnt].cost = w;
    edge[cnt].nxt = head[u];
    head[u] = cnt++;
}

int dfs1(int u, int pre)
{
    if(u == n)
    {
        return 1;
    }
    for( int i = head[u]; ~i; i = edge[i].nxt )
    {
        int v = edge[i].to;
        if(v == pre)
            continue;
        if(dfs1(v, u))
        {
            tt += edge[i].cost;
            edge[i].cost = 0;
            return 1;
        }
    }
    return 0;
}

void dfs2(int u, int pre)
{
    for(int i = 0; i <= t; i++)
        dp[u][i] = a[u];
    for( int i = head[u]; ~i; i = edge[i].nxt )
    {
        int v = edge[i].to;
        if(v == pre)
            continue;
        dfs2(v, u);
        int weit = edge[i].cost * 2;
        for(int j = t; j >= weit; j--)
            for(int k = 0; k <= j - weit; k++)
                dp[u][j] = max(dp[u][j], dp[v][k] + dp[u][j - weit - k]);
    }
}

int main()
{
    while(~scanf("%d%d", &n, &t))
    {
        init();
        for(int i = 1; i < n; i++)
        {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            addedge(u, v, w);
            addedge(v, u, w);
        }
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        tt = 0;
        dfs1(1, -1);
        if(tt > t)
        {
            puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!");
            continue;
        }
        t -= tt;
        dfs2(1, -1);
        printf("%d\n", dp[1][t]);
    }
    return 0;
}

抱歉!评论已关闭.