[Poi2011]Dynamite

problem:

1 unit of time after the lead on some point be ignited in a tree and its neighboring point lead will be ignited. If there is a point of explosive fuse is lit, then the dynamite will explode on this point.
The minimum time required to detonate all explosives.

solution:

DP + binary tree answers

Set $ ​​f1 [x] $ are not used then the point farthest distance x bomb 

    $ F2 [x] $ x denotes the distance of the nearest bomb had been ignited

$ F1 [x] = max (f1 [x], f1 [u]) $ u is the son of x

$ F2 [x] = min (f2 [x], f2 [u]) $ u x is the son

Postorder three cases

  IF (isbo [V] && F2 [V]> T) { 
            F1 [V] = max ( 0 , F1 [V]); // V is unsubstituted head point to take max 
        } 
    IF (F1 [V] + F2 [V] <= T) {F1 [V] = - 10000000 ;} // be covered
     IF (F1 [V] == T) {NUM ++; F2 [V] = 0 ; F1 [V] = - 10000000 ;} / / point then must 
    }

Note that DP is judged to root

code:

#include<stdio.h> 
#include<cstdlib> 
#include<ctime> 
#include<algorithm> 
using namespace std; 
#define maxnn 4000000 
#define inf 100000000 
int isbo[maxnn]; 
int f[maxnn];
int f1[maxnn],f2[maxnn]; 
int n,m; 
int t;
int cnt[maxnn],tr; 
int las[maxnn],nex[maxnn],en[maxnn],le[maxnn],tot; 
 inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
void add(int a,int b) 
{ 
    en[++tot]=b; 
    nex[tot]=las[a]; 
    las[a]=tot; 
} 
void dfs(int fa,int v)
{
    f[v]=fa;
    for(int i=las[v];i;i=nex[i]) 
    { 
        int u=en[i]; 
        if(u!=fa) 
        {
            dfs(v,u);
        }
    }
    cnt[++tr]=v;
 } 
int bfs() 
{     int num=0; 
    for(int y=1;y<=tr;y++)
    {
    int v=cnt[y];
    if(isbo[v]) f1[v]=0; 
    else f1[v]=-100000000; 
    f2[v]=inf; 
    for(int i=las[v];i;i=nex[i]) 
    { 
        int u=en[i]; 
        if(u!=f[v]) 
        { 
            f1[v]=max(f1[v],f1[u]+1); 
            f2[v]=min(f2[v],f2[u]+1); 
        }     
         
    } 
    if(isbo[v]&&f2[v]>t) {
            f1[v]=max(0,f1[v]);
        }
    if(f1[v]+f2[v]<=t) {f1[v]=-10000000;}
    if(f1[v]==t) {num++;f2[v]=0; f1[v]=-10000000;} 
    }
    return num; 
} 
bool ch() 
{ 
    int tot=bfs(); 
    if(f1[1]>=0) tot++;
    return tot<=m; 
} 
int main(){ 
    n=read();m=read();
    int s; 
    int x,y,z; 
    int l=0,r=n-1;
    for(int i=1;i<=n;i++) 
    { 
        isbo[i]=read();
    } 
    for(int i=1;i<n;i++) 
    { 
        x=read();
        y=read(); 
        add(x,y); 
        add(y,x); 
    } 
    dfs(1,1);
    int mid;
    while(l<=r) 
    { 
         mid=(l+r)/2; 
        t=mid;
        if(ch()) r=mid-1; 
        else 
        l=mid+1; 
    } 
    printf("%d",(l));
}

 

Guess you like

Origin www.cnblogs.com/OIEREDSION/p/11370668.html