不知道叫什么名字
题目描述
给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点。
之后你将依次收到k个指令,每个指令包含两个整数d和t,你需要沿着最短路在t步之内(包含t步)走到d点,如果不能走到,则停在最后到达的那个点。
请在每个指令之后输出你所在的位置。
输入格式
第一行包含三个正整数n,m,k(1<=m<=n<=1000000,1<=k<=1000000)。
接下来n-1行,每行包含两个正整数x,y(1<=x,y<=n),描述一条树边。
接下来k行,每行两个整数d,t(1<=d<=n,0<=t<=10^9),描述一条指令。
输出格式
输出一行,包含k个正整数,即执行每条指令后你所在的位置。
样例
样例输入
3 1 2
1 2
2 3
3 4
1 1
样例输出
3 2
code
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 10;
int n, vis[maxn], m, head[maxn * 2], tot, now, k, jl[maxn];
int depth[maxn], p[1000005][20], last = 1;
struct node {
int next, to;
} e[maxn * 2];
inline int read() {
int k = 0, f = 1;
char ch = getchar();
for (; !isdigit(ch); ch = getchar())
if (ch == '-')
f = -1;
for (; isdigit(ch); ch = getchar()) k = k * 10 + ch - '0';
return k * f;
}
void add(int x, int y) {
e[++tot] = (node){ head[x], y };
head[x] = tot;
}
void DFS(int rt) {
p[rt][0] = jl[rt];
depth[rt] = depth[jl[rt]] + 1;
for (int j = 0; p[rt][j] != 0; ++j) {
p[rt][j + 1] = p[p[rt][j]][j];
}
for (int x = head[rt]; x; x = e[x].next) {
int v = e[x].to;
if (jl[rt] != v)
p[v][0] = rt, jl[v] = rt, DFS(v);
}
}
inline int LCA(int u, int v) {
if (depth[u] < depth[v])
swap(u, v);
int d = depth[u] - depth[v];
for (register int j = 0; d; d >>= 1, ++j)
if (d & 1)
u = p[u][j];
if (u == v)
return v;
for (register int j = log(maxn); j >= 0; --j) {
if (p[u][j] != p[v][j]) {
u = p[u][j];
v = p[v][j];
}
}
return jl[u];
}
void DFS1(int u, int rt, int d) {
for (register int j = 0; d; d >>= 1, ++j) {
if (d & 1)
u = p[u][j];
}
now = u;
cout << u << " ";
}
int main() {
n = read(), m = read(), k = read();
for (register int i = 1; i < n; ++i) {
register int x = read(), y = read();
add(x, y);
add(y, x);
jl[y] = x;
}
for (register int i = 1; i <= n; ++i) {
if (!jl[i]) {
last = i;
break;
}
}
now = m;
DFS(last);
int t, rt, dis, dis1, dis2;
for (register int i = 1; i <= k; ++i) {
register int x = read(), t = read();
rt = LCA(x, now);
dis = depth[x] + depth[now] - depth[rt] * 2, dis1 = depth[x] - depth[rt],
dis2 = depth[now] - depth[rt];
if (depth[x] + depth[now] - depth[rt] * 2 <= t) {
now = x;
cout << x << " ";
} else if (dis2 >= t)
DFS1(now, rt, t);
else
DFS1(x, rt, dis - t);
}
return 0;
}