比赛 CSP2023-S模拟赛 评测结果 AAAAAAAAATTTTTTTTTTT
题目名称 坡伊踹 最终得分 45
用户昵称 Maple 运行时间 33.993 s
代码语言 C++ 内存使用 13.74 MiB
提交时间 2023-10-17 21:48:27
显示代码纯文本
#include <bits/stdc++.h>
#define foru(i,a,b) for(int i=(a);i<=b;++i)
#define ford(i,a,b) for(int i=(b);i>=b;--i)
typedef long long ll;
const int N=2e5;
const ll MX=1e18;
std::mt19937 rnd(time(0));
int n, q, root;

int rev[N+10];
struct Node {
    ll a, dis;
    int dep, size, dfn;
    int pa, son, top;
} node[N+10];

int num_edge, head[N+10];
struct Edge {
    int to, dis, nxt;
} road[N*2+10];

inline void add_edge(int u, int v, int w) {
    ++num_edge;
    road[num_edge].to = v;
    road[num_edge].dis = w;
    road[num_edge].nxt = head[u];
    head[u] = num_edge;
}

void dfs1(int p, int pa) {
    node[p].pa = pa;
    node[p].size = 1;
    for (int i = head[p]; i; i = road[i].nxt) {
        int v = road[i].to;
        if (v == pa) continue;
        node[v].dep = node[p].dep + 1;
        node[v].dis = node[p].dis + road[i].dis;
        dfs1(v, p);
        node[p].size += node[v].size;
        if (node[v].size > node[node[p].son].size) {
            node[p].son = v;
        }
    }
}

void dfs2(int p, int top) {
    static int dfn;
    node[p].top = top;
    rev[node[p].dfn = ++dfn] = p;
    if (!node[p].son) return;
    dfs2(node[p].son, top);
    for (int i = head[p]; i; i = road[i].nxt) {
        int v = road[i].to;
        if (v == node[p].pa || v == node[p].son) continue;
        dfs2(v, v);
    }
}

int lca(int x, int y) {
    if (x == y) return y;
    int tx = node[x].top, ty = node[y].top;
    while (tx != ty) {
        if (node[tx].dep < node[ty].dep) {
            std::swap(x, y);
            std::swap(tx, ty);
        }
        x = node[tx].pa;
        tx = node[x].top;
    }
    if (node[x].dep < node[y].dep) std::swap(x, y);
    return y;
}

int main() {
#ifndef LOCAL
    freopen("poitry.in", "r", stdin);
    freopen("poitry.out", "w", stdout);
#endif
    std::ios::sync_with_stdio(0);
    std::cin >> n >> q;
    root = rnd() % n + 1;
    std::cerr << root << std::endl;
    foru (i, 1, n) std::cin >> node[i].a;
    foru (i, 2, n) {
        int u, v, w;
        std::cin >> u >> v >> w;
        add_edge(u, v, w);
        add_edge(v, u, w);
    }
    node[root].dep = 1;
    dfs1(root, 0);
    dfs2(root, root);
    foru (i, 1, q) {
        int u, v;
        std::cin >> u >> v;
        int lca = ::lca(u, v);
        ll ans = std::max(
            node[lca].a,
            node[u].dis - node[lca].dis
        );
        for (int p = u; p != lca; p = node[p].pa) {
            ans = std::min(ans, std::max(
                node[p].a,
                node[u].dis - node[p].dis
            ));
        }
        for (int p = v; p != lca; p = node[p].pa) {
            ans = std::min(ans, std::max(
                node[p].a,
                node[u].dis - 2LL * node[lca].dis + node[p].dis
            ));
        }
        std::cout << ans << std::endl;
    }

    return 0;
}