POJ 1330

LCA 问题,因为查询操作很少,这次使用离线的Tarjan算法

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define WHITE -1
#define BLACK 0 
using namespace std;

const int maxn= 1e4+3;

vector > fa;
int cl[maxn], mk[maxn];
int qa, qb;
int dad[maxn];
int nca;

void Init(int n)
{
	fa.clear();
	fa.resize(n+3);
	memset(cl, WHITE, sizeof(cl));
	memset(mk, -1, sizeof(mk));
}
int Find(int a)
{
	if (a== dad[a]){
		return dad[a];
	}

	return dad[a]= Find(dad[a]);
}
void Union(int a, int b)
{
	a= Find(a);
	b= Find(b);
	if (a== b){
		return;
	}
	if (mk[b]< mk[a]){
		dad[a]= dad[b];
	}
	else{
		dad[b]= dad[a];
	}
}
void dfs(int u, int d)
{
	int sn;
	mk[u]= d;
	dad[u]= u;
	for (int i= 0; i< int(fa[u].size()); ++i){
		sn= fa[u][i];
		dfs(sn, d+1);
		dad[sn]= u;	
	}
	if (u==qa && BLACK== cl[qb]){
		nca= Find(qb);
		return;
	}
	if (u== qb && BLACK== cl[qa]){
		nca= Find(qa);
		return;
	}
	cl[u]= BLACK;
}
int main(void)
{
	int T, n;	
	int nd, snd, rt;
	scanf("%d", &T);

	while (T--){
		scanf("%d", &n);
		Init(n);
		for (int i= 0; i< n-1; ++i){
			scanf("%d %d", &nd, &snd);
			fa[nd].push_back(snd);
			mk[snd]= 0;
		}	
		scanf("%d %d", &qa, &qb);
		for (int i= 1; i<= n; ++i){
			if (mk[i]){
				rt= i;
				break;
			}
		}

		dfs(rt, 1);
		printf("%d\n", nca);

	}
	return 0;
}

你可能感兴趣的:(POJ 1330)