[CF708C]Centroids

Centroids

Subject to the effect

A tree, for each point, we delete any of its sides, and then connect any of its sides, it can be made at this point to find the center of gravity points after this operation

Range \ (n \) level

Solution

Ah, the first for a point \ (U \) , if all sub-tree (including the pile on his head) are less than the total number of points \ (n \) half certainly qualify

Then if \ (U \) subtree \ (\ {v \} \ ) there is a point \ (> {n \ over 2 } \) a \ (V1 \) , we need to find such a subtree a maximum number of points \ (<= {n \ over 2} \) subtrees \ (V2 \) .

To disconnect it, and then the \ (V2 \) even on \ (U \) , if this \ (V1 \) points \ (<= {n-\ over 2} \) , to satisfy the condition

Then the old idea of ​​a tree DP: first deal with a sub-tree, and then use the information subtree engage in a practice head on it.

code:

#include<bits/stdc++.h>
using namespace std;
struct qwq{
    int v;
    int nxt;
}edge[800010];
int cnt=-1;
int head[400010];
void add(int u,int v){
    edge[++cnt].nxt=head[u];
    edge[cnt].v=v;
    head[u]=cnt;
}
int fir[400010],sec[400010];
void up_max(int &x,int &y,int val){
    if(val>x){y=x;x=val;return;}
    else if(val>y){y=val;return;}
    else return;
}
int n;
int siz[400010];
int usiz[400010];
int g[400010];
void dfs(int u,int fa){
    siz[u]=1;
    for(int i=head[u];~i;i=edge[i].nxt){
        int v=edge[i].v;
        if(v==fa)continue;
        dfs(v,u);
        siz[u]+=siz[v];
        if(siz[v]>n/2)g[u]=v;
        if(siz[v]<=n/2)up_max(fir[u],sec[u],siz[v]);
        else up_max(fir[u],sec[u],fir[v]);
    }
    usiz[u]=n-siz[u];
    if(usiz[u]>n/2)g[u]=-1;
}
int um[400010];
void dfs2(int u,int fa){
    if(usiz[u]<=n/2){
        um[u]=usiz[u];
    }
    else if(fir[fa]==siz[u]){
        um[u]=max(um[fa],sec[u]);
    }
    else {
        um[u]=max(um[fa],fir[fa]);
    }
    for(int i=head[u];~i;i=edge[i].nxt){
        int v=edge[i].v;
        if(v==fa)continue;
        dfs2(v,u);
    }
}
bool ans[400010];
int main(){
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;++i){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v),add(v,u);
    }
    dfs(1,0);
    dfs2(1,0);
    for(int i=1;i<=n;++i){
        if((!g[i])||(g[i]==-1&&usiz[i]-um[i]<=n/2)||(g[i]!=-1&&siz[g[i]]-fir[g[i]]<=n/2))ans[i]=true;
    }
    for(int i=1;i<=n;++i){
        printf("%d ",ans[i]);
    }
}

Guess you like

Origin www.cnblogs.com/youddjxd/p/11617773.html