BZOJ 1776: [Usaco2010 Hol]cowpol 奶牛政坛 LCA + 树的直径

Code: 

#include <bits/stdc++.h> 
#define setIO(s) freopen(s".in","r",stdin) 
#define maxn 300000  
using namespace std;   
vector<int>G[maxn];  
int n,tot,root,edges; 
int fa[maxn];  
int hd[maxn],to[maxn],nex[maxn],top[maxn],dep[maxn],son[maxn],siz[maxn];   
void addedge(int u,int v) {
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;   
}
void dfs1(int u) {
    dep[u]=dep[fa[u]]+1, siz[u]=1; 
    for(int i=hd[u];i;i=nex[i]) { 
        int v=to[i];  
        if(v==fa[u]) continue; 
        dfs1(v), siz[u]+=siz[v]; 
        if(siz[v]>siz[son[u]]) son[u]=v;          
    }   
} 
void dfs2(int u,int tp) {
    top[u]=tp; 
    if(son[u]) dfs2(son[u], tp); 
    for(int i=hd[u];i;i=nex[i]) {
        int v=to[i]; 
        if(v==fa[u]||v==son[u]) continue;
        dfs2(v,v); 
    }
}
int LCA(int x,int y) {       
    while(top[x]^top[y]) {
        dep[top[x]] > dep[top[y]] ? x = fa[top[x]] : y = fa[top[y]]; 
    } 
    return dep[x]<dep[y]?x:y; 
}
int main() { 
    // setIO("input");  
    scanf("%d%d",&n,&tot);    
    for(int i=1;i<=n;++i) {
        int ty; 
        scanf("%d%d",&ty,&fa[i]); 
        if(!fa[i]) root=i; 
        else addedge(fa[i],i); 
        G[ty].push_back(i);  
    }      
    dfs1(root), dfs2(root,root);     
    for(int i=1;i<=tot;++i) { 
        int mx=0,ans=0; 
        for(int j=0;j<G[i].size();++j) { 
            if(dep[G[i][j]] > dep[mx]) mx = G[i][j]; 
        }  
        for(int j=0;j<G[i].size();++j) { 
            // printf("%d %d\n",mx,G[i][j]); 
            ans=max(ans, dep[mx] + dep[G[i][j]] - (dep[LCA(mx, G[i][j])] << 1));  
        } 
        printf("%d\n",ans);    
    }
    return 0; 
}

  

posted @ 2019-07-25 13:12  EM-LGH  阅读(150)  评论(0编辑  收藏  举报