比赛 |
树形数据结构进阶(再进阶) |
评测结果 |
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;
}