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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3586

    给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值cost表示破坏这条边的费用,叶子节点为前线。现要切断前线和司令部的联系,每次切断边的费用不能超过上限limit,问切断所有前线与司令部联系所花费的总费用少于m时的最小limit。1<=n<=1000,1<=m<=10^6

    dp[i]表示i节点为root的这个子树所破坏的最少费用,if(cost[i][i->son] <= limit) dp[i] += min(dp[i->son], cost[i][i->son]);

    二分limit,然后把limit放到dfs中判断是不是都能切断叶子节点的联系。

     1 #pragma comment(linker, "/STACK:102400000, 102400000")
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <ctime>
    10 #include <list>
    11 #include <set>
    12 #include <map>
    13 using namespace std;
    14 typedef long long LL;
    15 typedef pair <int, int> P;
    16 const int N = 1e5 + 5;
    17 int to[N << 1], Next[N << 1], cost[N << 1], head[N], tot, dp[N], inf = 1e6 + 7;
    18 
    19 void init() {
    20     memset(head, -1, sizeof(head));
    21     tot = 0;
    22 }
    23 inline void add_edge(int u, int v, int c) {
    24     Next[tot] = head[u];
    25     to[tot] = v;
    26     cost[tot] = c;
    27     head[u] = tot++;
    28 }
    29 void dfs(int u, int p, int limit) {
    30     dp[u] = inf;
    31     bool inter = false;
    32     for(int i = head[u]; ~i; i = Next[i]) {
    33         int v = to[i];
    34         if(v == p)
    35             continue;
    36         dfs(v, u, limit);
    37         if(!inter) {
    38             dp[u] = 0;
    39             inter = true;
    40         }
    41         if(cost[i] <= limit) {
    42             dp[u] += min(dp[v], cost[i]);
    43         } else {
    44             dp[u] += dp[v];
    45         }
    46     }
    47 }
    48 void solve() {
    49     int n, m, u, v, c;
    50     while(~scanf("%d %d", &n, &m) && (n || m)) {
    51         init();
    52         for(int i = 1; i < n; ++i) {
    53             scanf("%d %d %d", &u, &v, &c);
    54             add_edge(u, v, c);
    55             add_edge(v, u, c);
    56         }
    57         int l = 1, r = 1001;
    58         while(l < r) {
    59             int mid = (l + r) >> 1;
    60             dfs(1, -1, mid);
    61             if(dp[1] <= m) {
    62                 r = mid;
    63             } else {
    64                 l = mid + 1;
    65             }
    66         }
    67         if(r == 1001) {
    68             printf("-1
    ");
    69         } else {
    70             printf("%d
    ", l);
    71         }
    72     }
    73 }
    74 
    75 int main()
    76 {
    77     solve();
    78     return 0;
    79 }
  • 相关阅读:
    去掉Win10中的“此电脑”中的6个默认文件夹的方法
    Fastboot驱动及安装
    Fastboot驱动及安装
    JNI+NDK编程总结
    JNI+NDK编程总结
    20194742自动生成四则运算题第一版报告
    读构建之法现代软件工程随笔
    想法或创意
    ubuntu控制台乱码
    Java 为什么不支持多继承?
  • 原文地址:https://www.cnblogs.com/Recoder/p/5894168.html
Copyright © 2011-2022 走看看