histcat

histcat

P4281

Problem#

link

Solution#

Weaken the problem conditions

If there are two people, the meeting point must be at the lca of these two points

But here there are three people, what to do?

Guess It is found that it must be at the lca of two of them

Calculate the lca for each pair, and compare the three cases accordingly

Code#

#include<bits/stdc++.h>
const int N = 5e5 + 10;
using namespace std;
int n, m;
int read()
{
	int f = 1, x = 0;
	char ch = getchar();
	while(ch < '0' || ch > '9')
	{
		if(ch == '-') f = -1;
		ch = getchar();
	}

	while(ch >= '0' && ch <= '9')
	{
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return f * x;
}

int head[N], nxt[N << 1], to[N << 1], cnt = 1;
int fa[N][20];
int depth[N];
void add(int x, int y)
{
	to[++cnt] = y;
	nxt[cnt] = head[x];
	head[x] = cnt;
}

void dfs(int u, int fath)
{
	fa[u][0] = fath;
	depth[u] = depth[fath] + 1;
	for(int i = head[u]; i; i = nxt[i])
	{
		int v = to[i];
		if(v == fath) continue;
		dfs(v, u);
	}
}

void initlca()
{
	for(int j = 1;j < 20;j++)
	{
		for(int i = 1;i <= n;i++)
		{
			fa[i][j] = fa[fa[i][j - 1]][j - 1];
		}
	}
}

int querylca(int x, int y)
{
	if(depth[x] < depth[y]) swap(x, y);

	for(int j = 19;j >= 0;j--)
	{
		if(depth[fa[x][j]] >= depth[y])
		{
			x = fa[x][j];
		}
	}

	if(x == y) return x;

	for(int j = 19;j >= 0;j--)
	{
		if(fa[x][j] != fa[y][j])
		{
			x = fa[x][j], y = fa[y][j];
		}
	}

	return fa[x][0];
}

int main()
{
	n = read(), m = read();
	int a, b; 
	for(int i = 1;i <= n - 1;i++)
	{
		a = read(), b = read();
		add(a, b), add(b, a);
	}
	dfs(1, 0);
	initlca();
	int x, y, z;
	while(m --)
	{
		x = read(), y = read(), z = read();
		int xy = querylca(x, y);
		int yz = querylca(y, z);
		int xz = querylca(x, z);
		int xyz = querylca(xy, z);
		int yzx = querylca(yz, x);
		int xzy = querylca(xz, y);
		int xy_long = (-2) * depth[xy] + depth[x] + depth[y] - 2 * depth[xyz] + depth[z] + depth[xy];
		int yz_long = (-2) * depth[yz] + depth[y] + depth[z] - 2 * depth[yzx] + depth[x] + depth[yz];
		int xz_long = (-2) * depth[xz] + depth[x] + depth[z] - 2 * depth[xzy] + depth[y] + depth[xz];

		if(xy_long <= yz_long && xy_long <= xz_long)
		{
			printf("%d %d\n", xy, xy_long);
		}
		else if(yz_long <= xy_long && yz_long <= xz_long)
		{
			printf("%d %d\n", yz, yz_long);
		}
		else if(xz_long <= xy_long && xz_long <= yz_long)
		{
			printf("%d %d\n", xz, xz_long);
		}

	}
	return 0;
}
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.