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

    题意:  

      给定一个敌人的通信系统,是一棵树形,每个节点是一个敌人士兵,根节点是commander,叶子是前线,我们的目的是使得敌人的前线无法将消息传到commander,需要切断一些边,切断每条边需要一定的power,而我们有一台具有m点power的机器,问在使用此机器切断敌人通信系统的情况下,使得所切断边的最大边权达到最小是多少?(m<=100w,n<=1000)

    思路:

      其实就是要求所切断的边的最小瓶颈边。由于m比较大,不好枚举或者DP。但是他们具有线性的关系,就是瓶颈边越大,肯定越容易有解。可以二分枚举一下这条边的power值mid,然后进行一次DFS判断在此power在小于等于mid的情况下,花费最小是多少。如果花费<=m,则可以继续二分枚举。

     1 //#include <bits/stdc++.h>
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cmath>
     6 #include <map>
     7 #include <algorithm>
     8 #include <vector>
     9 #include <iostream>
    10 #define pii pair<int,int>
    11 #define INF 0x3f3f3f3f
    12 #define LL  long long
    13 using namespace std;
    14 const double PI  = acos(-1.0);
    15 const int N=1010;
    16 
    17 struct node
    18 {
    19     int from,to,cost,next;
    20     node(){};
    21     node(int from,int to,int cost,int next):from(from),to(to),cost(cost),next(next){};
    22 }edge[N*2];
    23 int head[N], n, m, edge_cnt;
    24 void add_node(int from,int to,int cost)
    25 {
    26     edge[edge_cnt]=node(from,to,cost,head[from]);
    27     head[from]=edge_cnt++;
    28 }
    29 
    30 int DFS(int t,int far,int mid)
    31 {
    32     node e;
    33     int sum=0;
    34     for(int i=head[t]; i!=-1; i=e.next)
    35     {
    36         e=edge[i];
    37         if( e.to==far )   continue;
    38         int tmp=DFS(e.to, t, mid);
    39         if( tmp>0 )   //有满足要求的
    40         {
    41             if( e.cost<tmp && e.cost<=mid )    sum+=e.cost; //更优解
    42             else                               sum+=tmp;
    43         }
    44         else                        //子树已经不满足要求,则必须在这一叉断开
    45         {
    46             if(e.cost>mid)  return 0;  //这叉都不能断开,则无解
    47             else            sum+=e.cost;
    48         }
    49     }
    50     return sum;         //只要sum就能使得t子树与叶子断开
    51 }
    52 
    53 
    54 int main()
    55 {
    56     //freopen("input.txt", "r", stdin);
    57     int a, b, c;
    58     while(scanf("%d%d",&n,&m), n+m)
    59     {
    60         edge_cnt=0;
    61         memset(head, -1, sizeof(head));
    62         for(int i=1; i<n; i++)
    63         {
    64             scanf("%d%d%d",&a,&b,&c);
    65             add_node(a,b,c);
    66             add_node(b,a,c);
    67         }
    68         int val=DFS(1,-1,1000); //试试最大值1000,若不行,则无解
    69         if(n==1 || val>m){puts("-1");continue;} //无解
    70 
    71         int L=1, R=1000;
    72         while(L<R)      //二分求最小的瓶颈边
    73         {
    74             int mid=L+(R-L)/2;
    75             int val=DFS(1,-1,mid);
    76             if(val>0 && val<=m)  R=mid;  //满足要求
    77             else                 L=mid+1;
    78         }
    79         printf("%d
    ",R);
    80     }
    81     return 0;
    82 }
    AC代码
  • 相关阅读:
    wex5 实战 框架拓展之2 事件派发与data刷新
    wex5 实战 框架拓展之1 公共data组件(Data)
    wex5 实战 HeidiSQL 导入Excel数据
    wex5 实战 手指触屏插件 hammer的集成与优劣
    wex5 实战 登陆帐号更换与用户id一致性
    wex5 实战 用户点评与提交设计技巧
    wex5 实战 省市县三级联动与地址薄同步
    wex5 实战 wex5与js的组件关系与执行顺序(父子与先后)
    wex5 实战 单页模式下的多页面数据同步
    [BZOJ]4237: 稻草人
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4836878.html
Copyright © 2011-2022 走看看