HDOJ 3586 Information Disturbing(二分答案+树DP)

题意:给一棵带权有根树,边权表示切断此边的代价,现有一台切边的机器,但它有一个上限值up limited power,只能切断边权不超过up limited power的边,现要切断根节点与所有叶子结点的联系,总代价即为所切边的边权和,给定最大代价m,求最小的up limited power。

数据范围:n<=1000,m<=1000000,1<=边权wi<=1000

分析:二分答案,然后树DP判断。复杂度为O(NlogW)

View Code
#include <stdio.h>

#include <string.h>

#include <algorithm>

using namespace std;

#define N 1001

int n,m,e;

int first[N],next[N<<1],v[N<<1],w[N<<1],d[N];

int dp[N];

void init()

{

    e=0;

    memset(first+1,-1,sizeof(first[0])*n);

    memset(d+1,0,sizeof(d[0])*n);

}

void add(int a,int b,int c)

{

    d[a]++;

    v[e]=b;

    w[e]=c;

    next[e]=first[a];

    first[a]=e++;

}

void dfs(int a,int fa,int up)

{

    if(d[a]==1 && v[first[a]]==fa)

    {

        dp[a]=-1;

        return;

    }

    int i,b;

    for(i=first[a];~i;i=next[i])

    {

        b=v[i];

        if(b==fa)    continue;

        dfs(b,a,up);

        if(dp[a]==-1)   continue;

        if(dp[b]==-1 && w[i]>up)

        {

            dp[a]=-1;

        }

        else if(dp[b]!=-1 && w[i]<=up)

        {

            dp[a]+=min(w[i],dp[b]);

        }

        else if(dp[b]!=-1)

        {

            dp[a]+=dp[b];

        }

        else

        {

            dp[a]+=w[i];

        }

    }

}

bool judge(int up)

{

    memset(dp+1,0,sizeof(dp[0])*n);

    dfs(1,0,up);

    if(dp[1]<0 || dp[1]>m)  return 0;

    return 1;

}

int main()

{

    while(scanf("%d%d",&n,&m),(n|m))

    {

        if(n==1)

        {

            puts("0");

            continue;

        }

        int a,b,c,maxw=0;

        init();

        for(int i=1;i<n;i++)

        {

            scanf("%d%d%d",&a,&b,&c);

            add(a,b,c);

            add(b,a,c);

            maxw=max(maxw,c);

        }

        if(judge(maxw)==0)

        {

            puts("-1");

            continue;

        }

        a=0,b=maxw;

        while(a+1!=b)

        {

            c=a+b>>1;

            if(judge(c))    b=c;

            else    a=c;

        }

        printf("%d\n",b);

    }

    return 0;

}

你可能感兴趣的:(format)