深い「NOI 10回の共同測定」

深い「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;
} 

おすすめ

転載: www.cnblogs.com/klauralee/p/11305433.html