1. 程式人生 > >HDU 3586 Information Disturbing(二分+樹形dp)

HDU 3586 Information Disturbing(二分+樹形dp)

題意 ios string txt 最小 stdin spl show else

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

題意:

給定一個帶權無向樹,要切斷所有葉子節點和1號節點(總根)的聯系,每次切斷邊的費用不能超過上限limit,問在保證總費用<=m下的最小的limit。

思路:

對於上限limit我們可以二分查找。然後就是樹形dp,看代碼就可以理解的。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6
#include<vector> 7 #include<stack> 8 #include<queue> 9 #include<cmath> 10 #include<map> 11 #include<set> 12 using namespace std; 13 typedef long long ll; 14 typedef pair<int,ll> pll; 15 const int INF = 0x3f3f3f3f; //INF如果開的比較大的話那麽cost要開long long,不然會超
16 const int maxn=1000+5; 17 18 int tot; 19 int n, m; 20 ll cost[maxn]; 21 int head[2*maxn]; 22 23 struct node 24 { 25 int v,w,next; 26 }e[2*maxn]; 27 28 void addEdge(int u, int v, int w) 29 { 30 e[tot].v=v; 31 e[tot].w=w; 32 e[tot].next=head[u]; 33 head[u]=tot++;
34 } 35 36 void dfs(int u, int fa, int x) 37 { 38 cost[u]=0; 39 bool flag=false; 40 for(int i=head[u];i!=-1;i=e[i].next) 41 { 42 int v=e[i].v; 43 if(v==fa) continue; 44 flag=true; 45 dfs(v,u,x); 46 if(e[i].w>x) cost[u]+=cost[v]; 47 else cost[u]+=min(cost[v],(ll)e[i].w); 48 } 49 if(!flag) cost[u]=INF; 50 } 51 52 int main() 53 { 54 //freopen("in.txt","r",stdin); 55 while(~scanf("%d%d",&n,&m)) 56 { 57 if(n==0 && m==0) break; 58 tot=0; 59 memset(head,-1,sizeof(head)); 60 int l=0,r=0; 61 for(int i=1;i<n;i++) 62 { 63 int u,v,w; 64 scanf("%d%d%d",&u,&v,&w); 65 addEdge(u,v,w); 66 addEdge(v,u,w); 67 r=max(r,w); 68 } 69 int ans=-1; 70 while(l<=r) 71 { 72 int mid=(l+r)/2; 73 dfs(1,-1,mid); 74 if(cost[1]<=m) {ans=mid;r=mid-1;} 75 else l=mid+1; 76 } 77 printf("%d\n",ans); 78 } 79 return 0; 80 }

HDU 3586 Information Disturbing(二分+樹形dp)