zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    GreenPlum 大数据平台--运维(二)
    GreenPlum 大数据平台--运维(一)
    GreenPlum 大数据平台--非并行备份(六)
    zabbix--高级篇-监控docker服务(一)
    GreenPlum 大数据平台--备份-邮件配置-gpcrondump & gpdbrestore(五)
    subprocess模块
    Python写随机发红包的原理流程
    粘包
    网络编程: 基于UDP协议的socket
    网络编程: 基于TCP协议的socket, 实现一对一, 一对多通信
  • 原文地址:https://www.cnblogs.com/tuchen/p/13764324.html
Copyright © 2011-2022 走看看