• Kill the tree 计蒜客42552 (重心


    新子树的重心一定在重儿子到根的路径上

    暴力向上跳即可

    #include<cstdio>
    #include<cstring> 
    #include<cmath>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 200010;
    const int INF = 1000000007; 
    
    int n;
    
    int h[maxn],cnt=0;
    
    struct E{
        int next,to;
    }e[maxn*2];
    
    void add(int u,int v){
        e[++cnt].to=v;
        e[cnt].next=h[u];
        h[u]=cnt;
    } 
    
    int sz[maxn],a[maxn],fa[maxn],son[maxn],b[maxn];
    
    int fin(int x,int u){
        int ma=INF,tt,an=x;
    //    tt = max(sz[son[x]],sz[u]-sz[x]);
        while(x!=fa[u] && max(sz[son[x]],sz[u]-sz[x])<=ma){
            if(max(sz[son[x]],sz[u]-sz[x])==ma){
                b[u] = x;
            }else if(max(sz[son[x]],sz[u]-sz[x])<ma){
                ma=max(sz[son[x]],sz[u]-sz[x]);
                an=x;
            }
            x = fa[x]; 
        }
        return an;
    }
    
    int dfs1(int u,int par){
        int nu = 0;
        fa[u] = par;sz[u]=1;
        for(int i=h[u];i!=-1;i=e[i].next){
            int v=e[i].to;
            if(v==par) continue;
            int sv = dfs1(v,u);
            if(sv>nu){
                nu = sv;
                son[u] = v;
            }
            sz[u] += sv;
        }
        return sz[u];
    }
    
    void dfs2(int u,int par){
        a[u] = u;
        
        for(int i=h[u];i!=-1;i=e[i].next){
            int v=e[i].to;
            if(v==par) continue;
            dfs2(v,u);
            if(v==son[u]){
                int x = a[son[u]];
                a[u] = fin(x,u);
            }
        }
    } 
    
    ll read(){ int s=0,f=1; char ch = getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch = getchar(); } while(ch>='0' && ch<='9'){ s = s*10 + ch - '0'; ch = getchar(); } return s*f; } 
    
    int main(){
        memset(h,-1,sizeof(h));
        n = read();
        
        int u,v;
        for(int i=1;i<n;i++){
            u = read(), v = read();
            add(u,v);
            add(v,u);
        }
        
        dfs1(1,0);
        dfs2(1,0);
        
        for(int i=1;i<=n;i++){
            if(b[i]!=0 && b[i]<a[i]) swap(a[i],b[i]);
            printf("%d",a[i]);
            if(b[i]) printf(" %d",b[i]);
            printf("
    ");  
        }
    
        return 0;
    }
  • 相关阅读:
    R语言基础入门
    调用arcpy包批量进行矢量掩膜提取
    一些js面试高频知识点的总结
    js实现五子棋人机对战源码
    编程题汇总,持续更新
    颜色字符串转换
    根据包名,在指定空间中创建对象
    JavaScript中[]+[] 、[]+{}、{}+[]、{}+{}的结果分析
    CSS命名规范
    谈谈浏览器的兼容性
  • 原文地址:https://www.cnblogs.com/tuchen/p/13764324.html
Copyright © 2020-2023  润新知