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
原文地址:https://www.cnblogs.com/137shoebills/p/7783898.html