深い「NOI 10回の共同測定」
このような最大通信ブロックことを最小限に抑えるために、明確に2つの答えを指します。
最初のルートノードを固定します。
果物のために、最初の治療は明らかに割り当てられていないサブツリー、その後、外向きに延びます。
各ノードレコードは、\は、シリコン(Si [] \)が負であれば、ドット割り当てられていないサブツリーの数は、代表点の絶対値が外側に延びていてもよいです。
各ノードのための\(私は\) :
点の統計的息子MIN最大数は、ノード自体は果実である場合、(を含む、と考えることができ、外向きに延びることができるよう\(Iは\)ノードがリンクブロックを割り当てることができ、それぞれが拡張することができますノードは確かに取り上げる(I \)\をそれだけで、ノード\(MIN \) )に有用です。
ポイント統計息子の未割り当てS.
若\(MIN \ GEQ S \)、\ (AS [X] = - (MIN-S)\) 。
そうでない場合、\シリコン(Si [X] = S \) 。
最後に、限り判定として\(SI [X] \当量 0 \) することができます。
#include<bits/stdc++.h>
#define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
#define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
#define mem(a,b) memset(a,b,sizeof a )
#define debug(a) cerr<<#a<<' '<<a<<"___"<<endl
using namespace std;
void in(int &r) {
static char c;
r=0;
while(c=getchar(),!isdigit(c));
do r=(r<<1)+(r<<3)+(c^48);
while(c=getchar(),isdigit(c));
}
const int mn=200005;
int head[mn],to[mn<<1],ne[mn<<1],cnt1;
#define link(a,b) link_edge(a,b),link_edge(b,a)
#define link_edge(a,b) to[++cnt1]=b,ne[cnt1]=head[a],head[a]=cnt1
#define travel(x) for(int q(head[x]);q;q=ne[q])
int lim,si[mn];
bool mark[mn];
void dfs(int f,int x){
si[x]=1;
int Min=0;
if(mark[x])Min=-lim;
travel(x)if(to[q]!=f){
dfs(x,to[q]);
Min=min(Min,si[to[q]]);
if(si[to[q]]>0)si[x]+=si[to[q]];
}
if(Min+si[x]<=0)si[x]=si[x]+Min;
}
bool check(int x){
lim=x;
dfs(0,1);
return si[1]<=0;
}
int main(){
freopen("deep.in","r",stdin);
freopen("deep.out","w",stdout);
int n,k,a,b;
in(n),in(k);
rep(q,1,n-1)in(a),in(b),link(a,b);
rep(q,1,k)in(a),mark[a]=1;
int l=n/k,r=n,ans=-1;
while(l<=r){
int mid=l+r>>1;
if(check(mid))ans=mid,r=mid-1;
else l=mid+1;
}
printf("%d\n",ans);
return 0;
}