zoukankan      html  css  js  c++  java
  • HDU3585 Information Disturbing 树形dp+二分

    http://acm.split.hdu.edu.cn/showproblem.php?pid=3586

     
    题意 : 给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超过上限limit,问在保证总费用<=m下的最小的limit。
     
    显然最小的总费用和最小的limit不能同时维护,那么只能在dfs中维护一个然后另一个用特殊的(朗诵)技巧解决…… 
    emmmmmmmmm……说白了就是二分求最小的limit,然后就没有下面了。
    算是普通难度,只要知道二分就很好写,虽然我开始没有想到(捂脸),还是意识不够。
     
    下面是代码  细长的代码非常丑所以删了一些换行,如果操作失误删掉一些奇怪东西导致不能AC,劳烦看官老爷自己再改改
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn=1010;
     8 int maxx=0;
     9 int t,n,m;
    10 int f[maxn]={};//子代lim值
    11 int he[maxn]={};//对应的和
    12 int vis[maxn]={};
    13 struct nod{
    14     int y;
    15     int next;
    16     int v;
    17 }e[2*maxn]={};
    18 int head[maxn]={},tot;
    19 void init(int x,int y,int v){
    20     e[++tot].y=y;
    21     e[tot].v=v;
    22     e[tot].next=head[x];
    23     head[x]=tot;
    24 }
    25 bool dfs(int x,int ls,int sum){
    26     int y,v;
    27     vis[x]=1;
    28     for(int i=head[x];i;i=e[i].next){
    29         y=e[i].y; v=e[i].v;
    30         if((!vis[y])){
    31             if(dfs(y,ls,sum-he[x])){
    32                 if(f[y]!=0){
    33                     if(v<=ls&&v<he[y]){
    34                         f[x]=max(f[x],v); he[x]+=v;
    35                     }else{
    36                         f[x]=max(f[x],f[y]); he[x]+=he[y];
    37                     }
    38                 }else{
    39                     if(v<=ls){
    40                         f[x]=max(f[x],v); he[x]+=v;
    41                     }else{
    42                         if(x==1){ return 0; }
    43                         f[x]=0; return 1;
    44                     }
    45                 }if(he[x]>sum){
    46                     if(x==1){ return 0; }
    47                     f[x]=0; return 1;
    48                 }
    49             }else{ return 0; }
    50         }
    51     }
    52     return 1;
    53 }
    54 void yu(){
    55     tot=0; maxx=0;
    56     memset(f,0,sizeof(f));
    57     memset(he,0,sizeof(he));
    58     memset(vis,0,sizeof(vis));
    59     memset(head,0,sizeof(head));
    60 }
    61 void yu2(){
    62     memset(vis,0,sizeof(vis));
    63     memset(f,0,sizeof(f));
    64     memset(he,0,sizeof(he));
    65 }
    66 int doit(){
    67     int l=1,r=maxx;
    68     while(r-l>1){
    69         int md=(l+r)/2; yu2();
    70         if(dfs(1,md,m)){ r=md; }
    71         else{ l=md; }
    72     }yu2();
    73     if(dfs(1,l,m)){ return l; }
    74     yu2();
    75     if(dfs(1,r,m)){ return r; }
    76     return -1;
    77 }
    78 int main(){
    79     for(;1;){
    80         yu();
    81         scanf("%d%d",&n,&m);
    82         if(n==0&&m==0){ break; }
    83         int x,y,v;
    84         for(int i=1;i<n;i++){
    85             scanf("%d%d%d",&x,&y,&v);
    86             maxx=max(maxx,v);
    87             init(x,y,v);
    88             init(y,x,v);
    89         }
    90         cout<<doit()<<endl;
    91     }
    92     return 0;
    93 }
    View Code
  • 相关阅读:
    Aruduino un0 spi oled官方代码
    排序--之快速排序
    用arduino UNO R3板为pro mini板烧录bootloaders
    数码管显示
    gdb高级功能与配置
    ROS中调试c++程序
    自引用结构--之创建双向遍历的链表
    数据文件——将从键盘设备文件读取文本将其写入显示器设备文件
    数据文件——将文本写入显示器设备文件
    ifcfg-eth0
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7783898.html
Copyright © 2011-2022 走看看