HDU 1011 (树背包)

来源:互联网 发布:apple淘宝旗舰店 编辑:程序博客网 时间:2024/05/02 02:18

坑点是特判。

#include <bits/stdc++.h>using namespace std;#define maxn 111#define maxm 222struct node {    int from, to, next;}edge[maxm];int bug[maxn], brain[maxn];int n, m, head[maxn];int ans;int dp[maxn][maxn];int degree[maxn];void add_edge (int from, int to, int i) {    node &e = edge[i];    e.from = from, e.to = to, e.next = head[from], head[from] = i;}void dfs (int u, int fa) {    for (int i = bug[u]; i <= m; i++) {        dp[u][i] = brain[u];    }    for (int i = head[u]; i != -1; i = edge[i].next) {        int v = edge[i].to;        if (v == fa)            continue;        dfs (v, u);        for (int j = m; j >= bug[u]; j--) {            for (int k = 1; j+k <= m; k++) {                dp[u][j+k] = max (dp[u][j+k], dp[u][j]+dp[v][k]);            }        }    }}int main () {    //freopen ("in", "r", stdin);    while (cin >> n >> m) {        if (n == -1 && m == -1)            break;        for (int i = 1; i <= n; i++) {            cin >> bug[i] >> brain[i];            bug[i] = ceil (bug[i]*1.0/20);        }        memset (head, -1, sizeof head);        int u, v;        int cnt = 0;        memset (degree, 0, sizeof degree);        for (int i = 1; i < n; i++) {            cin >> u >> v;            add_edge (u, v, cnt++);            add_edge (v, u, cnt++);            degree[u]++;            degree[v]++;        }        if (m == 0) {            printf ("0\n");            continue;        }        for (int i = 2; i <= n; i++)            if (degree[i] == 1)                bug[i] = max (1, bug[i]); //如果是叶子节点 至少需要一个士兵        memset (dp, 0, sizeof dp);        dfs (1, 0);        printf ("%d\n", dp[1][m]);    }    return 0;}


0 0
原创粉丝点击