Zhy's Blog~

View My GitHub Profile

Archive
Categories
About

倍增法求LCA

  要说搞了这么久比赛还没学过倍增LCA,实在是惭愧。这次驱动我这个懒癌患者学习一下倍增LCA的是这道题——CF609E-Minimum spanning tree for each edge。说起来有时候学习的动力就是这么产生的——Idea我有,工具不会用。

LCA

入门

  先来扯一扯概念——LCA(Lowest Common Ancestor),最近公共祖先。在一棵有根树中,节点v到根root的路径上所有的节点都叫v的“祖先”,LCA(u,v) 即两个点u,v,距离它们最近的公共祖先,也就是树中“最低”(深度最高,离root最远)的公共祖先。

用途

算法

  求LCA有多种算法:

倍增LCA


void dfs(int x,int d){
	depth[x] = d;
	visited[x] = true;
	for (vector<int>::iterator it = edge[x].begin();it != edge[x].end();it++)
		if (!visited[*it]) dfs(*it,d+1);
}

void lcabinarylifting(int n){
	for (int j = 1;j < MAXB;j++)
		for (int i = 1;i <= n;i++)
			if (~father[i][j-1])
				father[i][j] = father[father[i][j-1]][j-1];
}

int findlca(int u,int v){
	if (depth[u] < depth[v]) swap(u,v);
	for (int b = MAXB-1;b >= 0;b--)
		if (depth[father[u][b]] >= depth[v])
			u = father[u][b];
	if (u == v) return u;
	for (int b = MAXB-1;b >= 0;b--)
		if (father[u][b] != father[v][b])
			u = father[u][b],v = father[v][b];
	return father[u][0];
}

测试题目

POJ1330 模板题,可供测试各种LCA算法。
code 倍增求LCA参考代码。

CF609E 倍增LCA求任意两点路径上的最大边权。
blog entry 题解链接。

© 个人原创,未经允许,不得转载!

Copyright © 2015-2016 zhyack. All Rights Reserved.

如对文章有任何疑问,请移步问题聚集区一览~