【USACO】 奶牛政坛

【题目链接】

          点击打开链接

【算法】

         tarjan算法求LCA

【代码】

      

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

你可能感兴趣的:(最近公共祖先,tarjan算法)