社区讨论

36求条

P2783有机化学之神偶尔会做作弊参与者 1已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mj2nhj8v
此快照首次捕获于
2025/12/12 17:14
2 个月前
此快照最后确认于
2025/12/14 10:20
2 个月前
查看原帖
CPP
#include <bits/stdc++.h>

using namespace std;
#define ll long long
#define ull unsigned long long
#define db double
#define sz(x) ((int)x.size())
#define inf (1 << 30)
#define pb push_back
typedef pair<int, int> PII;
const int N = 1e4 + 7;
const int P = 998244353;
int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (!(ch >= '0' && ch <= '9')) {if (ch == '-') f = -f;ch = getchar();}
	while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}
	return x * f;
}
/*
思路:边双缩点,求lca
*/
int n, m;
int dfn[N], low[N], times, bcc;
int stk[N], top, bel[N];
int dep[N], dp[N][21];
vector <int> edges[N], G[N];
void add_edges(int x, int y) {
	edges[x].pb(y);
	edges[y].pb(x);
}
void insert(int x, int y) {
	G[x].pb(y);
}
inline void tarjan(int u, int fa) {
	dfn[u] = low[u] = ++times;
	stk[++top] = u;
	bool mark = false;
	for (auto v : edges[u]) {
		if (v == fa && !mark) mark = 1;
		else if (!dfn[v]) {
			tarjan(v, u);
			low[u] = min(low[u], low[v]);
		}else {
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (low[u] == dfn[u]) {
		bcc++;
		while (1) {
			int v = stk[top--];
			bel[v] = bcc;
			if (v == u) break;
		}
	}
}
void dfs(int u, int fa) {
	for (auto v : G[u]) {
		if (v == fa) continue;
		dep[v] = dep[u] + 1;
		dp[v][0] = u;
		dfs(v, u);
	}
}
void pre_init() {
	for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i, i); // tarjan
	for (int i = 1; i <= n; i++) {
		for (auto v : edges[i]) {
			if (bel[i] != bel[v]) {
				insert(bel[v], bel[i]);
			}
		}
	}
	dfs(1, 1);
	for (int j = 1; j <= 19; j++) {
		for (int i = 1; i <= bcc; i++) {
			dp[i][j] = dp[dp[i][j - 1]][j - 1];
		}
	}
}
int get_lca(int x, int y){
	if (dep[x] < dep[y]) swap(x,y);
	int d = dep[x] - dep[y];
	for(int i = 0; d; i++, d >>= 1){
		if (d & 1) {
			x = dp[x][i];
		}
	}
	if (x != y) {
		for (int i = 19; i >= 0; i--){
			if (dp[x][i] != dp[y][i]) {
				x = dp[x][i];
				y = dp[y][i];
			}
		}
		x = dp[x][0];	
	}
	return x;
}
void two(int x) {
	vector<int> ve;
	while (x) {
		ve.pb(x % 2);
		x /= 2;
	}
	reverse(ve.begin(), ve.end());
	for (auto v : ve)
		printf("%d", v);
	putchar('\n');
}
int main() {
	n = read(), m = read();
	for (int i = 1; i <= m; i++) {
		int x = read(), y = read();
		add_edges(x, y);
	}
	// do sth on there
	pre_init();
	// for (int i = 1; i <= n; i++) printf("%d\n", dep[i]);
	int q = read();
	while (q--) {
		int x = read(), y = read();
		two(dep[x] + dep[y] - 2 * dep[get_lca(x, y)] + 1);
	}
	return 0;
}


回复

3 条回复,欢迎继续交流。

正在加载回复...