《关于我们WA题太多导致皮卡丘看不下去把妙蛙种子电死于是我们现在叫不听不听,飞鞋点金|

superPG

园龄:5年粉丝:2关注:10

2022-07-22 14:52阅读: 25评论: 0推荐: 0

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]; //xy同深度的情况下,向上移动。
	}
	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

本文作者:superPG

本文链接:https://www.cnblogs.com/superPG/p/16505761.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   superPG  阅读(25)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 いつも何度でも 伊藤サチコ
いつも何度でも - 伊藤サチコ
00:00 / 00:00
An audio error has occurred.

呼んでいる 胸のどこか奥で

いつも心踊る 夢を見たい

かなしみは 数えきれないけれど

その向こうできっと あなたに会える

繰り返すあやまちの そのたび ひとは

繰り返すあやまちの そのたび ひとは

ただ青い空の 青さを知る

果てしなく 道は続いて見えるけれど

この両手は 光を抱ける

さよならのときの 静かな胸

さよならのときの 静かな胸

ゼロになるからだが 耳をすませる

生きている不思議 死んでいく不思議

花も風も街も みんなおなじ

nananan lalala lululu

nananan lalala lululu

呼んでいる 胸のどこか奥で

いつも何度でも 夢を描こう

かなしみの数を 言い尽くすより

同じくちびるで そっとうたおう

閉じていく思い出の そのなかにいつも

閉じていく思い出の そのなかにいつも

忘れたくない ささやきを聞く

こなごなに砕かれた 鏡の上にも

新しい景色が 映される

はじまりの朝の静かな窓

はじまりの朝の静かな窓

ゼロになるからだ 充たされてゆけ

海の彼方には もう探さない

輝くものは いつもここに

わたしのなかに 見つけられたから

nananan lalala lululu

nananan lalala lululu