比赛 CSP2023-S模拟赛 评测结果 AAAAAAAAATTTTTTTTTTT
题目名称 坡伊踹 最终得分 45
用户昵称 HzmQwQ 运行时间 33.475 s
代码语言 C++ 内存使用 20.57 MiB
提交时间 2023-10-17 21:28:04
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>

#define MAXN 200005
#define INF 0x3f3f3f3f3f3f3f3f
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))

using namespace std;

typedef long long ll;

struct node {
    int to, wgt;
};

int n, q, a[MAXN], fa[MAXN], dep[MAXN], dn, dfn[MAXN], mi[19][MAXN];
ll dis[MAXN];
vector <node> T[MAXN];

int get(int x, int y) {
    return dfn[x] < dfn[y] ? x : y;
}

void dfs(int u, int fr) {
    dfn[u] = ++dn;
    mi[0][dfn[u]] = fr;
    fa[u] = fr;
    for(node nxt : T[u]) {
        int v = nxt.to;
        if(v != fr) {
            dis[v] = dis[u] + (ll)nxt.wgt;
            dfs(v, u);
        }
    }
    return ;
}

int lca(int u, int v) {
    if(u == v) return u;
    int du = dfn[u], dv = dfn[v];
    if(du > dv) swap(du, dv);
    int d = __lg(dv - du);
    return get(mi[d][du + 1], mi[d][dv - (1 << d) + 1]);
}

int query(int u, int v) {
    ll ret = INF;
    int lc = lca(u, v);
    int pt = u;
    ll ndis = 0LL, mdis = 0LL;
    while(pt != lc) {
        ndis = dis[u] - dis[pt];
        ret = min(ret, max(ndis, a[pt]));
        pt = fa[pt];
    }
    int qt = v;
    while(qt != lc) {
        mdis = dis[u] + dis[qt] - 2LL * dis[lc];
        ret = min(ret, max(mdis, a[qt]));
        qt = fa[qt];
    }
    ndis = dis[u] - dis[lc];
    ret = min(ret, max(ndis, a[lc]));
    return ret;
}

int main() {
    freopen("poitry.in", "r", stdin);
    freopen("poitry.out", "w", stdout);
    scanf("%d %d", &n, &q);
    for(int i = 1; i <= n; i++) scanf("%d", a + i);
    for(int i = 1; i < n; i++) {
        int _u, _v, _w;
        scanf("%d %d %d", &_u, &_v, &_w);
        T[_u].push_back((node){_v, _w});
        T[_v].push_back((node){_u, _w});
    }
    dfs(1, 0);
    for(int i = 1; i <= __lg(n); i++)
        for(int j = 1; j + (1 << i) - 1 <= n; j++) mi[i][j] = get(mi[i - 1][j], mi[i - 1][j + (1 << i - 1)]);
    for(int i = 1; i <= q; i++) {
        int qu, qv;
        scanf("%d %d", &qu, &qv);
        printf("%lld\n", query(qu, qv));
    }
    return 0;
}