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