【USACO】 奶牛政坛
【题目链接】
【算法】
tarjan算法求LCA
【代码】
#include<bits/stdc++.h> #define MAXN 200010 #pragma GOC optimize("O2") using namespace std; int n,k,i,p,fa,q; int a[MAXN],visit[MAXN],parent[MAXN],maxn[MAXN], depth[MAXN],x[MAXN],y[MAXN],z[MAXN],ans[MAXN]; vector<int> son[MAXN],vec[MAXN]; int find(int x) { if (parent[x] == x) return x; parent[x] = find(parent[x]); return parent[x]; } void dfs(int dep,int d) { int i; depth[dep] = d; for (i = 0; i < son[dep].size(); i++) dfs(son[dep][i],d+1); } void tarjan(int u) { int i; parent[u] = u; visit[u] = 1; for (i = 0; i < vec[u].size(); i++) { if (y[vec[u][i]] == u && visit[x[vec[u][i]]]) z[vec[u][i]] = find(x[vec[u][i]]); if (x[vec[u][i]] == u && visit[y[vec[u][i]]]) z[vec[u][i]] = find(y[vec[u][i]]); } for (i = 0; i < son[u].size(); i++) { if (!visit[son[u][i]]) { tarjan(son[u][i]); parent[son[u][i]] = u; } } } int main() { scanf("%d%d",&n,&k); for (i = 1; i <= n; i++) { scanf("%d%d",&a[i],&p); if (p != 0) son[p].push_back(i); else fa = i; } dfs(fa,0); for (i = 1; i <= n; i++) { if (depth[i] > depth[maxn[a[i]]]) maxn[a[i]] = i; } for (i = 1; i <= n; i++) { if (maxn[a[i]] != i) { ++q; x[q] = maxn[a[i]]; y[q] = i; vec[maxn[a[i]]].push_back(q); vec[i].push_back(q); } } tarjan(fa); for (i = 1; i <= q; i++) { ans[a[x[i]]] = max(ans[a[x[i]]],depth[x[i]] + depth[y[i]] - 2 * depth[z[i]]); } for (i = 1; i <= k; i++) printf("%d\n",ans[i]); return 0; }