| 比赛 |
2025.10.24 |
评测结果 |
AAAAAAAAATTTTTTTTTTT |
| 题目名称 |
坡伊踹 |
最终得分 |
45 |
| 用户昵称 |
梦那边的美好ME |
运行时间 |
45.355 s |
| 代码语言 |
C++ |
内存使用 |
23.10 MiB |
| 提交时间 |
2025-10-24 10:28:29 |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int n,q;
int a[210000];
vector<pair<int,int>> g[210000];
int depth[210000];
ll dist[210000];
int fa[18][210000];
void dfs(int u,int p,int d,ll dis){
fa[0][u]=p;
depth[u]=d;
dist[u]=dis;
for (auto &e:g[u]){
int v=e.first,w=e.second;
if (v==p) continue;
dfs(v,u,d + 1,dis + w);
}
}
void solve(){
dfs(1,0,0,0);
for (int k=1;k<18;k++){
for (int i=1;i<=n;i++){
fa[k][i]=fa[k-1][fa[k-1][i]];
}
}
}
int lca(int u,int v){
if (depth[u]<depth[v]) swap(u,v);
int diff=depth[u]-depth[v];
for (int k=17;k>=0;k--){
if (diff >> k & 1){
u=fa[k][u];
}
}
if (u==v) return u;
for (int k=17;k>=0;k--){
if (fa[k][u] != fa[k][v]){
u=fa[k][u];
v=fa[k][v];
}
}
return fa[0][u];
}
ll get_dist(int u,int v){
int l=lca(u,v);
return dist[u]+dist[v]-2*dist[l];
}
bool check(int u,int v,int ans){
int l=lca(u,v);
int x=u;
while (1){
if (a[x]<=ans && get_dist(x,u)<=ans) return 1;
if (x==l) break;
x=fa[0][x];
}
x=v;
while (x!=l){
if (a[x]<=ans&&get_dist(x,u)<=ans) return 1;
x=fa[0][x];
}
return 0;
}
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=0;i<n-1;i++){
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
g[u].push_back({v,w});
g[v].push_back({u,w});
}
solve();
while (q--){
int u,v;
scanf("%d %d",&u,&v);
if (u==v){
printf("%d\n",max(a[u],0));
continue;
}
int l=0,r=1e9;
while (l<r){
int mid=(l+r)/2;
if (check(u,v,mid)){
r=mid;
}else l=mid + 1;
}
printf("%d\n",l);
}
return 0;
}