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; }