比赛 |
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;
}