不知道叫什么名字

题目描述

给定一棵有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;
}
posted @ 2020-07-08 18:45  hyskr  阅读(229)  评论(0编辑  收藏  举报