#191-[LCA]祖孙询问

版权声明:反正也没有人会转,下一个 https://blog.csdn.net/drtlstf/article/details/85011369

Description

已知一棵n个节点的有根树。有m个询问。每个询问给出了一对节点的编号x和y,询问x与y的祖孙关系。

Input

输入第一行包括一个整数n表示节点个数。

接下来n行每行一对整数对a和b表示a和b之间有连边。如果b是-1,那么a就是树的根。

第n+2行是一个整数m表示询问个数。

接下来m行,每行两个正整数x和y。

Output

对于每一个询问,输出1:如果x是y的祖先,输出2:如果y是x的祖先,否则输出0。

10
234 -1
12 234
13 234
14 234
15 234
16 234
17 234
18 234
19 234
233 19
5
234 233
233 12
233 13
233 15
233 19
  • Sample Input

1
0
0
0
2
  • Sample Output

HINT

对于30%的数据,nm≤1000。

对于100%的.据nm≤40000,每个节点的编号都不超过40000。

应该也是LCA......

#include <iostream>
#include <cstring>
#include <vector>
#include <map>

#define SIZE 40010

using namespace std;

struct qedge
{
	int to, id;
};

map<int, int> mp;
vector<qedge> qgraph[SIZE];
vector<int> graph[SIZE];
int pre[SIZE], indegree[SIZE], lca[SIZE], qx[SIZE], qy[SIZE], cnt;
bool visited[SIZE];

int find(int x) // 找祖先
{
	return (pre[x] != x) ? pre[x] = find(pre[x]) : x;
}

void tarjan(int u, int pr) // 找LCA
{
	int i, v;
	
	for (i = 0; i < graph[u].size(); ++i)
	{
		v = graph[u][i];
		if (v == pr)
		{
			continue;
		}
		tarjan(v, u);
		pre[v] = u;
	}
	visited[u] = true;
	for (i = 0; i < qgraph[u].size(); ++i)
	{
		v = qgraph[u][i].to;
		if (visited[v])
		{
			lca[qgraph[u][i].id] = find(v);
		}
	}
	
	return;
}

int getnumber(void) // 全部变成1~n之间的数
{
	int x;
	
	scanf("%d", &x);
	if (x == -1)
	{
		return -1;
	}
	if (mp[x] > 0)
	{
		return mp[x]; // 一个map辅助
	}
	
	return mp[x] = ++cnt;
}

int main(void)
{
	int n, m, x, y, i, root;
	
	scanf("%d", &n);
	for (i = 1; i <= n; ++i)
	{
		pre[i] = i;
		x = getnumber(); // 建图
		y = getnumber();
		if (y == -1)
		{
			root = x;
		}
		else
		{
			graph[x].push_back(y);
			graph[y].push_back(x);
		}
	}
	scanf("%d", &m);
	for (i = 1; i <= m; ++i)
	{
		qx[i] = getnumber(); // 询问
		qy[i] = getnumber();
		qgraph[qx[i]].push_back({qy[i], i});
		qgraph[qy[i]].push_back({qx[i], i});
	}
	
	tarjan(root, -1); // 求LCA
	
	for (i = 1; i <= m; ++i)
	{
		if (lca[i] == qx[i]) // 按照不同情况输出
		{
			printf("1\n");
		}
		else if (lca[i] == qy[i])
		{
			printf("2\n");
		}
		else
		{
			printf("0\n");
		}
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/drtlstf/article/details/85011369
lca