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)); }