• [HDU3586]Information Disturbing(DP + 二分)


    传送门

    题意:给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超过上限limit,问在保证总费用<=m下的最小的limit

    二分答案,再 DP,看看最终结果是否小于 m

    ——代码

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #define N 1001
     5 #define max(x, y) ((x) > (y) ? (x) : (y))
     6 
     7 int n, m, cnt, ans;
     8 int a[N], sum[N], head[N], to[N << 1], val[N << 1], next[N << 1];
     9 bool vis[N];
    10 
    11 inline int read()
    12 {
    13     int x = 0, f = 1;
    14     char ch = getchar();
    15     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
    16     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
    17     return x * f;
    18 }
    19 
    20 inline void add(int x, int y, int z)
    21 {
    22     to[cnt] = y;
    23     val[cnt] = z;
    24     next[cnt] = head[x];
    25     head[x] = cnt++;
    26 }
    27 
    28 inline void dfs(int u, int x)
    29 {
    30     int i, v;
    31     vis[u] = 1;
    32     for(i = head[u]; i ^ -1; i = next[i])
    33     {
    34         v = to[i];
    35         if(!vis[v])
    36         {
    37             dfs(v, x);
    38             if(val[i] <= x)
    39             {
    40                 if(val[i] < sum[v]) sum[u] += val[i];
    41                 else sum[u] += sum[v];
    42             }
    43             else sum[u] += sum[v];
    44         }
    45     }
    46 }
    47 
    48 inline bool check(int x)
    49 {
    50     memset(vis, 0, sizeof(vis));
    51     memset(sum, 0, sizeof(sum));
    52     for(int i = 2; i <= n; i++)
    53         if(a[i] == 1)
    54             sum[i] = m + 1;
    55     dfs(1, x);
    56     return sum[1] <= m;
    57 }
    58 
    59 int main()
    60 {
    61     int i, x, y, z, mid;
    62     while(1)
    63     {
    64         cnt = 0;
    65         n = read();
    66         m = read();
    67         if(!n && !m) break;
    68         memset(a, 0, sizeof(a));
    69         memset(head, -1, sizeof(head));
    70         for(i = 1; i < n; i++)
    71         {
    72             a[x = read()]++;
    73             a[y = read()]++;
    74             z = read();
    75             add(x, y, z);
    76             add(y, x, z);
    77         }
    78         x = 1, y = m, ans = -1;
    79         while(x <= y)
    80         {
    81             mid = (x + y) >> 1;
    82             if(check(mid)) ans = mid, y = mid - 1;
    83             else x = mid + 1;
    84         }
    85         printf("%d
    ", ans);
    86     }
    87     return 0;
    88 }
    View Code
  • 相关阅读:
    数据库系列之查询(4)
    数据库系列之查询(3)
    数据库系列之查询(2)
    数据库系列之查询(1)
    数据库系列之视图
    数据库系列之数据管理(删除数据)
    数据库系列之数据管理(更新数据)
    数据库系列之数据管理(插入数据)
    数据库管理之数据表管理(2)
    数据库管理之数据表管理(1)
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/7044648.html
Copyright © 2020-2023  润新知