hdu 3586 Information Disturbing(树形dp)

来源:互联网 发布:淘宝刷好评怎么做 编辑:程序博客网 时间:2024/06/01 22:30

题目大概说一棵树有边权,要删掉一些边,使叶子到达不了树根1且删掉边的权和小于等于m,问删掉边中最大权的最小值能是多少。

考虑问题规模,与转移的时间复杂度,用这么个状态dp:

  • dp[u][k]表示在u结点为根的子树中,使其叶子到达不了根的,删掉边的最大权小于等于k的最小被删边权和


#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 10010#define MOD 1000000007const int MAXN = 1010;struct Edge{    int to,w,next;} edge[MAXN<<1];int tot,head[MAXN];int n,m,mx;long long dp[1010][1010];void add(int a,int b,int c){    edge[tot].to = b;    edge[tot].w = c;    edge[tot].next = head[a];    head[a] = tot++;}void dfs(int u,int w){    if(u != 1)        for(int i = w; i <= mx; i++)            dp[u][i] = w;    long long tmp[1010] = {0};    for(int i = head[u]; i != -1; i = edge[i].next)    {        int v = edge[i].to;        dfs(v,edge[i].w);        for(int j = 1; j <= mx; j++)            tmp[j] += dp[v][j];    }    for(int i = 1; i <= mx; i++)    {        if(!tmp[i])            continue;        dp[u][i] = min(dp[u][i],tmp[i]);    }}int main(){    int t,C = 1;    //scanf("%d",&t);    while(scanf("%d%d",&n,&m) &&(n+m))    {        tot = 0;        memset(head,-1,sizeof(head));        mx = 0;        for(int i = 1; i < n; i++)        {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            add(a,b,c);            mx = max(mx,c);        }        for(int i = 0; i <= n; i++)            for(int j = 0; j <= mx; j++)            dp[i][j] = 1000010;        dfs(1,0);        int ans = -1;        for(int i = 1; i <= mx; i++)            if(dp[1][i] <= m)            {                ans = i;                break;            }        printf("%d\n",ans);    }    return 0;}


0 0