LOJ 6042 flea Kingdom prime minister

LOJ 6042 flea Kingdom prime minister

The meaning of problems

Flea Kingdom unrest broke out, the king at the same time quell the riots, the country needs at the local flea handpicked prime minister a person to do.

Because of the complexity of the situation at that time, many have fleas do not want a puppet prime minister, with the prime minister's hat, and finally braved the danger of being overthrown and beheaded, but there is a flea but would like to have the most unique fashion.

Originally, he intended to teach, he has published his views in academic terms, they get a lot of flea agree, but then I heard the prime minister handpicked to flea the country, he decided to break up the idea want to teach, as long as he felt the national interest, regardless of their life and death can be, where to go to avoid because of work to give their blessing or a scourge or near the job? So he decided to stand up and take the job.

However, when the Imperial way King is very strange, flea Kingdom can be seen as a tree, it considers that the prime minister must be a better service for fleas, so he will choose a to all nodes in the distance and the smallest node , and this node in Imperial, If there are multiple nodes to satisfy the minimum distance and optionally a.

However, unrest flea country is too much, so the tree's shape may also change, that is, the tree may have several edges disappear, if this happens, then there will be side appear the same number of , in order to ensure that the entire structure is still a tree .

Now the flea would like to know each node flea If you want to be King James, at least how many edges disappear (of course, will have the same number of sides appear). As a true fan only fleas, you can help him solve this problem?

Data range \ (n \ le 10 ^ 6 \)

Problem-solving ideas

For convenience of drafting, we put a tree is called a too heavy , and if and only if it is larger than the \ (\ frac {n} { 2} \)

The center of gravity is a point, if and only if all the sub-trees it is not too heavy to.

First, the tree's center of gravity, it must answer is \ (0 \) .

For non-gravity, it is too heavy to be bound to a sub-tree, and containing the center of gravity.

For splinter sub-tree, we put it on and we expect it to be connected to the focus point is not necessarily bad.

We take such a greedy strategy: first, the center of gravity of the split sub-tree, from largest to smallest. If other sub-tree at a time center of gravity and the center of gravity is not too heavy , you can put this whole pieces of tree splinter.

Next we prove the correctness of this strategy.

First, when the size of the center of gravity and the center of gravity of the other sub-tree is not too heavy , while the sub-tree where the center of gravity is still too heavy , then the splinter certain optimal center of gravity.

Because we consider the center of gravity of any one sub-tree is not too heavy , then retain only a sub-tree must be legitimate.

We focus splinter retention focus is actually part of a sub-tree, so be sure legitimate.

If at this time the focus is too heavy , then the sub-tree where the center of gravity must be too heavy

So be sure to put the center of gravity to split not too heavy

the above.

Code

We put all the focus of the sub-tree sort in descending order, then two.

I finished it.

#include<bits/stdc++.h>
#define now edge[i].v
#define go(x) for(int i=head[x];i;i=edge[i].nxt)
using namespace std;
const int sz=1e6+7;
const int inf=1e9;
int n;
int tot,rt;
int u,v,cnt;
int head[sz];
int ans[sz];
int mx[sz],siz[sz];
int s[sz],pos[sz],sum[sz]; 
struct Edge{
    int v,nxt;
}edge[sz<<1];
void make_edge(int u,int v){
    edge[++cnt]=(Edge){v,head[u]};head[u]=cnt;
    edge[++cnt]=(Edge){u,head[v]};head[v]=cnt;
}
bool cmp(int x,int y){
    return siz[x]>siz[y];
}
void getrt(int x,int fa){
    siz[x]=1;
    go(x) if(now!=fa){
        getrt(now,x);
        mx[x]=max(mx[x],siz[now]);
        siz[x]+=siz[now];
    } 
    mx[x]=max(mx[x],n-siz[x]);
    if(mx[x]<tot) tot=mx[x],rt=x;
}
void dfs(int x,int fa){
    siz[x]=1;
    go(x) if(now!=fa){
        dfs(now,x);
        siz[x]+=siz[now];
    }
}
void Dfs(int x,int fa,int id){
    int w=n-siz[x];
    if(n-siz[id]<=n/2) ans[x]=(x!=id);
    else if(w-(sum[pos[id]-1])<=n/2){
        int l=0,r=pos[id]-1;
        while(l<r){
            int mid=(l+r)>>1;
            if(w-sum[mid]<=n/2||n-siz[id]-sum[mid-1]<=n/2) r=mid;
            else l=mid+1;
        }
        ans[x]=l;
    }
    else{
        int l=pos[id]+1,r=tot;
        while(l<r){
            int mid=(l+r)>>1;
            if(w-sum[mid]+siz[id]<=n/2||n-sum[mid-1]<=n/2) r=mid;
            else l=mid+1;
        }
        ans[x]=l-1;
    }
    go(x) if(now!=fa) Dfs(now,x,id);
}
void solve(){
    tot=0;
    go(rt) s[++tot]=now;
    sort(s+1,s+tot+1,cmp);
    for(int i=1;i<=tot;i++){
        pos[s[i]]=i;
        sum[i]=sum[i-1]+siz[s[i]];
    }
    go(rt) Dfs(now,rt,now);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        make_edge(u,v);
    }
    tot=inf,rt=0;
    getrt(1,0);
    dfs(rt,0);
    solve();
    for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
}

Guess you like

Origin www.cnblogs.com/river-flows-in-you/p/11936950.html