【题目链接】
【算法】
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;
}