hdu 3586 Information Disturbing(树形dp)

来源:互联网 发布:黑魔棒淘宝 编辑:程序博客网 时间:2024/06/07 07:08

Information Disturbing

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3586

解题思路:

题目大意:

给你n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值val表示破坏这条边的费用,叶子节点为前

线。现要切断前线和司令部的联系,每次切断边的费用不能超过上限limit,问切断所有前线与司令部联系所花费的总费用少于m时的

最小limit。

算法思想:

容易看出这题要用树形DP不难,但是难在想到要二分。对于上限进行二分,然后通过树形DP进行判断。

坑点:INF设置不能太大。。。

AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#define INF 1000005;using namespace std;const int N = 1005;struct node{    int v,val;    node(){}    node(int _v,int _val){        v = _v; val = _val;    }};vector<node> edge[N];int n,m;int dp[N];void dfs(int u,int fa,int lim){    int flag = 0; //标记是不是叶子结点    dp[u] = 0;    int len = edge[u].size();    for(int i = 0; i < len; ++i){        int v = edge[u][i].v;        if(v != fa){            flag = 1;            dfs(v,u,lim);            if(edge[u][i].val <= lim)                dp[u] += min(dp[v],edge[u][i].val);            else                dp[u] += dp[v];        }    }    if(!flag)   //叶子结点无穷大        dp[u] = INF;}int main(){    while(scanf("%d%d",&n,&m),n+m){        for(int i = 0; i <= n; ++i)            edge[i].clear();        int MAX = 0;        int u,v,val;        for(int i = 1; i < n; ++i){            scanf("%d%d%d",&u,&v,&val);            edge[u].push_back(node(v,val));            edge[v].push_back(node(u,val));            if(val > MAX)                MAX = val;        }        int l = 1,r = MAX,ans = -1;        while(l <= r){            int mid = (l+r)>>1;            dfs(1,-1,mid);            if(dp[1] <= m){                ans = mid;                r = mid-1;            }else                l = mid+1;        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击