2022.7.22 AcWing LeetCode

LCA 倍增

#include <bits/stdc++.h>
using namespace std;

const int N = 1e3 + 10;

int T;
int n, m;
int h[N], e[N * 2], ne[N * 2];
// f 为倍增函数,存储每个节点i,取j次父节点的节点。
// d 为深度函数,存储每个节点的深度
// dist 为距离函数,当前节点root到根节点的距离。
int f[N][16], d[N], dist[N];
int q[N];
int idx;

void add(int a, int b) {
	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void bfs(int root) {
	memset(d, 0x3f, sizeof d);  //用q数组模拟队列;
	d[0] = 0, d[root] = 1;
	q[0] = root;
	int hh = 0, tt = 0;
	while (hh <= tt) {
		int t = q[hh++];                //每次取出队头元素,并遍历其链接边所对应的每个点
		for (int i = h[t]; i != -1; i = ne[i]) {
			int y = e[i];
			if (d[y] > d[t] + 1) {      //如果 该点没有被更新过,说明,这是子节点,需要更新深度并计算f值。
				d[y] = d[t] + 1;
				q[++tt] = y;
				dist[y] = dist[t] + e[i];   //同时维护dist数组。
				f[y][0] = t;                //特殊情况下,父节点的f值需要单独维护。
				for (int j = 1; j <= 15; j++) { //y的f值,根据一般情况下的状态转移方程即可得到。
					f[y][j] = f[f[y][j - 1]][j - 1];
				}
			}
		}
	}
}

int lca(int x, int y) {
	if (d[x] < d[y])
		swap(x, y); //确保x的深度要比y深。
	for (int i = 15; i >= 0; i--) { //注意枚举的顺序。
		if (d[f[x][i]] >= d[y])
			x = f[x][i]; //把深度更深的x向上移动。
	}
	if (x == y)
		return x;
	for (int i = 15; i >= 0; i--) {
		if (f[x][i] != f[y][i])
			x = f[x][i], y = f[y][i]; //x和y同深度的情况下,向上移动。
	}
	return f[x][0];
}

int main() {
	scanf("%d", &T);
	while (T--) {
		idx = 0;
		memset(h, -1, sizeof  h);
		memset(f, 0, sizeof f);
		memset(d, 0, sizeof d);
		memset(dist, 0, sizeof dist);

		scanf("%d %d", &n, &m);

		for (int i = 1; i <= n; i++) {
			int a, b;
			scanf("%d %d", &a, &b);
			if (a != -1) {
				add(i, a);
				add(a, i);
			}
			if (b != -1) {
				add(i, b);
				add(b, i);
			}
		}

		bfs(1);

		while (m--) {
			int a, b;
			scanf("%d %d", &a, &b);
			int t = lca(a, b);
			int ans = dist[a] + dist[b] - dist[t] * 2;
			printf("%d\n", ans);
		}

	}
	return 0;
}

LeetCode题解:
https://leetcode.cn/problems/set-intersection-size-at-least-two/solution/by-sen-xm-42ad/
该题解情况4中,需要再次判断的是当前右端点和上一区间右端点重合,这时候再取的一个数就不是当前区间右端点了,而是右端点-1,否则会取重。
SBLeetCode不让我修改题解。

此外在本题中,sort使用Lambda表达式来实现元素比较的逻辑。相关内容如下:
https://blog.csdn.net/dong_beijing/article/details/81057918
https://blog.csdn.net/BRAVE_NO1/article/details/109752534?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~default-1-109752534-blog-81057918.pc_relevant_aa_2&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~default-1-109752534-blog-81057918.pc_relevant_aa_2&utm_relevant_index=1

posted @ 2022-07-22 14:52  superPG  阅读(20)  评论(0编辑  收藏  举报