hdu 3586(ツリーDP+二分回答)

4631 ワード

Information Disturbing
Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 1085    Accepted Submission(s): 396
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 5 1 3 2 1 4 3 3 5 5 4 2 6 0 0
 
Sample Output

   
   
   
   
3
 
Author
alpc86
 
本題はいくつかの単一の重み値がlimitを超えず、これらの辺を加えて重み値がsumを超えない辺を取り除いた後、ルートノードとすべての葉ノードのつながりを切断することができ、最小のlimitを求めることを要求する.
まずlimitを選択しなければならなくて、列挙することができて、列挙の過程の中で二分法で加速します;いくつかの辺の古い動態の計画を選んで、木の形のDP
            現在のノードuがリーフノードであると仮定し、dp[u]=無限大にする.
            現在のノードuが非リーフノードである場合:
                                                      len[u][v]<=limitの場合、dp[u]=Σ(dp[v],len[u][v])は、vがノードの子供ノードである
                                                     len[u][v]>limitの場合、dp[u]+=dp[v]
 
本題が大牛を転載したのは、主に彼の隣接表のためによく実現すべきで、私の最適化よりずっと多くて、無方向図を構築する時にこのテンプレートを使うことを提案します
 
/*
HDU 3586
  DP+    
*/
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;


const int MAXN=1010;
const int INF=1000010;//         ,    ,    
struct Node
{
    int to;
    int next;
    int w;
}edge[MAXN*2];//     
int head[MAXN];//      ,          

int tol;
int dp[MAXN];

int min(int a,int b)
{
	return a<b?a:b;
}

void add(int a,int b,int w)
//       
{
    edge[tol].to=a;
    edge[tol].next=head[b];
    edge[tol].w=w;
    head[b]=tol++;
    edge[tol].to=b;
    edge[tol].next=head[a];
    edge[tol].w=w;
    head[a]=tol++;
}


void init()
//     
{
    tol=0;
    memset(head,-1,sizeof(head));
}


void dfs(int u,int pre,int limit)
//  DP       ,    DP  DFS
{
    int i,flag=false;//         
    dp[u]=0;
    for(i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;//        
        if(v==pre)
			continue;//      ,             
        flag=true;
        dfs(v,u,limit);
        if(edge[i].w<=limit)
			dp[u]+=min(dp[v],edge[i].w);//          ,      ,                                       
        else 
			dp[u]+=dp[v];//        ,    ,                     
    }
    if(!flag)
		dp[u]=INF;//       
}


int main()
{
    int n,m,i;
    int a,b,w;
    int l,r,mid;
    while(scanf("%d%d",&n,&m)==2)
    {
        if(n==0&&m==0)break;
        init();
        r=0;
        for(i=1;i<n;i++)
        {
            scanf("%d%d%d",&a,&b,&w);
            add(a,b,w);
            if(w>r)r=w;
        }

        l=1;
        int ans=-1;
        while(l<=r)
        {
            mid=(l+r)/2;
            dfs(1,-1,mid);
            if(dp[1]<=m)
            {
                ans=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        printf("%d
",ans); } return 0; }