"NOI ten joint measurement" deep

"NOI ten joint measurement" deep

To minimize such that the maximum communication block, clearly points to two answers.

Fixing a first root node.

For a fruit, the first treatment apparently subtree unassigned, then extends outwardly.

Each node record a \ (Si [] \) , number of dots unallocated subtree, if it is negative, the absolute value of the representative points may extend outwardly.

For each node \ (I \) :

Statistical sons MIN maximum number of points may extend outwardly, if the node itself is the fruit, can be considered, including (as \ (I \) node can be assigned a link block, and each can be extended node will certainly take up \ (i \) node, it is only \ (MIN \) is useful).

Points Statistics sons unallocated S.

\ (MIN \ GEQ S \) , \ (as [x] = - (MIN-S) \) .

Otherwise, \ (Si [X] = S \) .

Finally, as long as the judgment \ (si [x] \ leq 0 \) can.

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

Guess you like

Origin www.cnblogs.com/klauralee/p/11305433.html