比赛 树形数据结构进阶(再进阶) 评测结果 AATTTTTTTTTTTTTTTTTT
题目名称 谈笑风生 最终得分 10
用户昵称 LikableP 运行时间 72.008 s
代码语言 C++ 内存使用 16.19 MiB
提交时间 2025-04-19 10:55:29
显示代码纯文本
#include <cstdio>
#include <queue>
using namespace std;

const int MAXN = 3e5 + 10;

struct EDGE {
	int v, next;
} edge[MAXN << 1];

int head[MAXN], edgeNum;
void AddEdge(int u, int v) {
	edge[++edgeNum].v = v;
	edge[edgeNum].next = head[u];
	head[u] = edgeNum;
}

int n, q;
int depth[MAXN];
int grd[MAXN][19];

void dfs(int now, int fa) {
	depth[now] = depth[fa] + 1;
	grd[now][0] = fa;
	for (int i = 1; i <= 18; ++i) {
		grd[now][i] = grd[grd[now][i - 1]][i - 1];
	}
	for (int i = head[now]; i; i = edge[i].next) {
		if (edge[i].v == fa) continue;
		dfs(edge[i].v, now);
	}
}

bool bfs(int st, int ed, int k) {
	queue <int> qn, qk, qf;
	qn.push(st);
	qk.push(0);
	qf.push(0);
	while (!qn.empty()) {
		int now = qn.front(), nk = qk.front(), fa = qf.front();
		qn.pop(), qk.pop(), qf.pop();
		if (nk > k) continue;
		if (now == ed) return true;
		for (int i = head[now]; i; i = edge[i].next) {
			if (edge[i].v == fa) continue;
			qn.push(edge[i].v), qk.push(nk + 1), qf.push(now);
		}
	}
	return false;
}

bool check(int x, int y) { // x -> ... -> y
	if (depth[y] <= depth[x]) return false;
	for (int i = 18; i >= 0; --i) {
		if (depth[grd[y][i]] >= depth[x]) {
			y = grd[y][i];
		}
	}
	return x == y;
}

int main() {
	freopen("laugh.in", "r", stdin);
	freopen("laugh.out", "w", stdout);
	scanf("%d %d", &n, &q);
	for (int i = 1; i <= n - 1; ++i) {
		int u, v;
		scanf("%d %d", &u, &v);
		AddEdge(u, v);
		AddEdge(v, u);
	}
	dfs(1, 0);
	while (q--) {
		int p, k;
		scanf("%d %d", &p, &k);
		int ans = 0;
		for (int a = p; a == p; ++a) {
			for (int b = 1; b <= n; ++b) {
				if (a == b) continue;
				if (!bfs(a, b, k)) continue;
				for (int c = 1; c <= n; ++c) {
					if (a == c || b == c) continue;
					if (!(check(a, c) && check(b, c))) continue;
					ans++;
				}
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}