hdu 3586 二分+树形dp

来源:互联网 发布:网络购物纠纷立案 编辑:程序博客网 时间:2024/05/29 12:42

Information Disturbing

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 1335    Accepted Submission(s): 489


Problem Description
In the battlefield , an effective way to defeat enemies is to break their communication system.
The information department told you that there are n enemy soldiers and their network which have n-1 communication routes can cover all of their soldiers. Information can exchange between any two soldiers by the communication routes. The number 1 soldier is the total commander and other soldiers who have only one neighbour is the frontline soldier.
Your boss zzn ordered you to cut off some routes to make any frontline soldiers in the network cannot reflect the information they collect from the battlefield to the total commander( number 1 soldier).
There is a kind of device who can choose some routes to cut off . But the cost (w) of any route you choose to cut off can’t be more than the device’s upper limit power. And the sum of the cost can’t be more than the device’s life m.
Now please minimize the upper limit power of your device to finish your task.
 

Input
The input consists of several test cases.
The first line of each test case contains 2 integers: n(n<=1000)m(m<=1000000).
Each of the following N-1 lines is of the form:
ai bi wi
It means there’s one route from ai to bi(undirected) and it takes wi cost to cut off the route with the device.
(1<=ai,bi<=n,1<=wi<=1000)
The input ends with n=m=0.
 

Output
Each case should output one integer, the minimal possible upper limit power of your device to finish your task.
If there is no way to finish the task, output -1.
 

Sample Input
5 51 3 21 4 33 5 54 2 60 0
 

Sample Output
3


题意:切断一定的边,使得所有叶子节点与根节点断开,限制条件是断开的边权之和小于某一值,且每一条边权小于某一值x,求x的最小值。

一看题就知道是二分+树形dp判断可行性, INF上界不能太大,否则会溢出,因为这个wa好多次。

代码:

/* ***********************************************Author :xianxingwuguanCreated Time :2014-2-6 16:15:10File Name :1.cpp************************************************ */#pragma comment(linker, "/STACK:102400000,102400000")#include <stdio.h>#include <iostream>#include <algorithm>#include <sstream>#include <stdlib.h>#include <string.h>#include <limits.h>#include <string>#include <time.h>#include <math.h>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define INF 1000000#define eps 1e-8#define pi acos(-1.0)typedef long long ll;const int maxn=4009;int head[maxn],tol;struct node{    int next,to,val;    node(){};    node(int _next,int _to,int _val):next(_next),to(_to),val(_val){}}edge[5*maxn];void add(int u,int v,int val){    edge[tol]=node(head[u],v,val);    head[u]=tol++;}int dfs(int u,int fa,int num){    int sum=0,flag=0;    for(int i=head[u];i!=-1;i=edge[i].next){        int v=edge[i].to;        if(v==fa)continue;        int tt=dfs(v,u,num);        if(tt>edge[i].val&&edge[i].val<=num)            tt=edge[i].val;        sum+=tt;        flag=1;    }    if(!flag)return INF;    return sum;}int main(){     //freopen("data.in","r",stdin);     //freopen("data.out","w",stdout);     int i,j,k,m,n;     while(~scanf("%d%d",&n,&m)){         if(n==0||m==0)break;         memset(head,-1,sizeof(head));tol=0;         int l=1,r=1010;         for(i=1;i<n;i++){             int p;             scanf("%d%d%d",&j,&k,&p);             add(j,k,p);             add(k,j,p);         }         int ans=-1;         while(l<=r){             int mid=(l+r)>>1;             if(dfs(1,1,mid)<=m)                 ans=mid,r=mid-1;             else l=mid+1;         }         cout<<ans<<endl;         //cout<<dfs(1,-1,3)<<" "<<dfs(1,-1,4)<<endl;     }     return 0;}


1 0