zoukankan      html  css  js  c++  java
  • hdu 3586 树形dp+二分

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

    链接:点我

    题目要问的是最小的最大限制,必然二分答案
    然后对于每一个值,树形DP判定是否可行
    dp[i]表示要切断以i为根的其它所有子树的最小代价。
    其中设定叶子结点的代价为无穷大
    那么对于某一个非叶子结点,要切断一棵子树就有两种选择,切断以孩子为根的子树或者切断根与孩子的边。
    如果根与孩子的边大于限制,那就取无穷大。
    最后判断1号结点的总花费是否小于等于m
    注意:无穷大不要取太大,否则会连续相加溢出

    Sample Input
    5 5
    1 3 2
    1 4 3
    3 5 5
    4 2 6
    0 0
     
    Sample Output
    3

     注意没结果要输出-1

    INF大小要注意搞好

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<map>
     8 using namespace std;
     9 #define MOD 1000000007
    10 const int INF=1000010;
    11 const double eps=1e-5;
    12 typedef long long ll;
    13 #define cl(a) memset(a,0,sizeof(a))
    14 #define ts printf("*****
    ");
    15 const int MAXN=1005;
    16 int n,m,tt,tot=0,head[MAXN],dp[MAXN];
    17 int maxw;
    18 struct edge
    19 {
    20     int to,next;
    21     int w;
    22 }edge[MAXN*2];
    23 void addedge(int a,int b,int w)
    24 {
    25     edge[tot].to=a;
    26     edge[tot].next=head[b];
    27     edge[tot].w=w;
    28     head[b]=tot++;
    29 }
    30 void init()
    31 {
    32     memset(head,-1,sizeof(head));
    33     tot=0;
    34     maxw=0;
    35 }
    36 void dfs(int u,int pre,int limit)
    37 {
    38     int flag=0;
    39     for(int i=head[u];i!=-1;i=edge[i].next)
    40     {
    41         int v=edge[i].to;
    42         if(v==pre)  continue;
    43         flag=1;
    44         dfs(v,u,limit);
    45         if(edge[i].w<=limit)    dp[u]+=min(dp[v],edge[i].w);    //切子树,或者切与子树相连的边
    46         else    dp[u]+=dp[v];   //只能切断子树
    47     }
    48     if(!flag)   dp[u]=INF;  //叶子不能切哦
    49 }
    50 int main()
    51 {
    52     int i,j,k;
    53     #ifndef ONLINE_JUDGE
    54     freopen("1.in","r",stdin);
    55     #endif
    56     while(scanf("%d%d",&n,&m)!=EOF)
    57     {
    58         init();
    59         if(n==0&&m==0)  break;
    60         int u,v,w;
    61         for(i=1;i<n;i++)
    62         {
    63             scanf("%d%d%d",&u,&v,&w);
    64             addedge(u,v,w);
    65             addedge(v,u,w);
    66             if(maxw<w)  maxw=w;
    67         }
    68         int l=1,r=maxw;
    69         int ans=-1;
    70         while(l<=r)
    71         {
    72             cl(dp);
    73             int mid=(l+r)>>1;
    74             dfs(1,-1,mid);
    75             if(dp[1]<=m)
    76             {
    77                 ans=mid;
    78                 r=mid-1;
    79             }
    80             else    l=mid+1;
    81         }
    82         printf("%d
    ",ans);
    83     }
    84 }
  • 相关阅读:
    第 6 章 存储
    第 6 章 存储
    第 6 章 存储
    第 6 章 存储
    第 6 章 存储
    vba:csv文件批量转换为xls的宏
    MySQL安装教程 推荐5.xx版本
    Cover Letter Draft for Application
    团队角色自测问卷答案
    联想Global future leader program面试
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4330318.html
Copyright © 2011-2022 走看看