zoukankan      html  css  js  c++  java
  • HDU 3586 Information Disturbing 树形DP+二分

    Information Disturbing

    Problem Description
     
    In the battlefield , an effective way to defeat enemies is to break their communication system.
    The information department told you that there are n enemy soldiers and their network which have n-1 communication routes can cover all of their soldiers. Information can exchange between any two soldiers by the communication routes. The number 1 soldier is the total commander and other soldiers who have only one neighbour is the frontline soldier.
    Your boss zzn ordered you to cut off some routes to make any frontline soldiers in the network cannot reflect the information they collect from the battlefield to the total commander( number 1 soldier).
    There is a kind of device who can choose some routes to cut off . But the cost (w) of any route you choose to cut off can’t be more than the device’s upper limit power. And the sum of the cost can’t be more than the device’s life m.
    Now please minimize the upper limit power of your device to finish your task.
     
    Input
     
    The input consists of several test cases. 
    The first line of each test case contains 2 integers: n(n<=1000)m(m<=1000000).
    Each of the following N-1 lines is of the form:
    ai bi wi
    It means there’s one route from ai to bi(undirected) and it takes wi cost to cut off the route with the device.
    (1<=ai,bi<=n,1<=wi<=1000)
    The input ends with n=m=0.
     
    Output
     
    Each case should output one integer, the minimal possible upper limit power of your device to finish your task. 
    If there is no way to finish the task, output -1.
     
    Sample Input
     
    5 5 1 3 2 1 4 3 3 5 5 4 2 6 0 0
     
    Sample Output
     
    3
     

    题意:

      给你n点的树,每条边有权值

      你可以任意选边切断,使得最后的所有原图中的叶子节点都不与1相连

      这会花费切断边的权值cost,切断的边中 权值最大边 w

      必须满足的是 cost不超过给定的m,且使得w尽量小

      输出这个最小的w,没有满足条件的 -1

    题解:

      我们二分答案

      对于得到limit,我们在树上选边切断的时候 保持被切断的边的权值不超过它就是了,每次DP处理即可

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include<vector>
    #include <algorithm>
    using namespace std;
    const int N = 1e3+20, M = 1e2+10, mod = 1e9+7, inf = 1e9+1000;
    typedef long long ll;
    
    struct edge{int to,next,w;}e[N * 4];
    int head[N] , t , n , m , cost, dp[N];
    void add(int u,int v,int w) {e[t].to=v,e[t].w=w,e[t].next=head[u];head[u]=t++;}
    void init() {t=1;memset(head,-1,sizeof(head));}
    void dfs(int u,int fa,int limit) {
        int ret = 0, cnt = 0;
        for(int i=head[u];i!=-1;i=e[i].next) {
            int to = e[i].to;
            int value = e[i].w;
            if(to == fa) continue;
            cnt += 1;
            dfs(to,u,limit);
            if(dp[to] == -1) {
                if(value <= limit) ret += value;
                else return ;
            }else {
                if(value <= limit) ret += min(dp[to] , value);
                else ret += dp[to];
            }
        }
        if(cnt)dp[u] = ret;
    }
    int check(int limit) {
        memset(dp,-1,sizeof(dp));
        dfs(1,-1,limit);
        if(dp[1] == -1) return 0;
        else {
            cost = dp[1];
            return 1;
        }
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)) {
            if(!n&&!m) break;
            int mx = 0;
            init();
            for(int i=1;i<n;i++) {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                mx = max(c,mx);
                add(a,b,c);
                add(b,a,c);
            }
            int l = 0, r = mx, ans = -1;
            while(l<=r) {
                int mid = (l+r) / 2;
                cost = 0;
                int OK = check(mid);
                if(OK && cost <= m) {
                    r = mid - 1;
                    ans = mid;
                }else {
                    l = mid + 1;
                }
            }
            if(ans == -1) puts("-1");
            else if(check(ans)&&cost <= m) cout<<ans<<endl;
            else puts("-1");
        }
    }
  • 相关阅读:
    学习笔记008之Task
    问题: ActivityManager: Warning: Activity not started, its current task has been brought to the front
    问题; No label views point to this text field with an android:labelFor="@+id/@+id/editTextNumber1" attribute
    学习笔记001之[Android开发视频教学].01_06_Android当中的常见控件
    学习笔记002之学习资料
    学习笔记001之环境配置
    设计模式之代理模式
    C# Enum转换
    Json数据序列化对象,及对象序列化为Json格式
    groupby以后取每组前n行
  • 原文地址:https://www.cnblogs.com/zxhl/p/5689527.html
Copyright © 2011-2022 走看看