比赛 CSP2023-S模拟赛 评测结果 AAAAAAAAATTTTTTTTTTT
题目名称 坡伊踹 最终得分 45
用户昵称 ┭┮﹏┭┮ 运行时间 33.488 s
代码语言 C++ 内存使用 26.98 MiB
提交时间 2023-10-17 20:31:11
显示代码纯文本
#include <bits/stdc++.h> 
using namespace std;
typedef long long ll;
const int N = 2e5+10;
int n,q,t;
ll a[N],di[N];
struct made{
    int ver,nx;
    ll ed;
}e[N<<2];
int hd[N],tot,lca[N][20],d[N];
int v[N];
void add(int x,int y,ll z){
    tot++;
    e[tot].ver = y,e[tot].nx = hd[x],e[tot].ed = z,hd[x] = tot;
}
void dfs(int x){
    v[x] = 1;
    for(int i = hd[x];i;i = e[i].nx){
        int y = e[i].ver;ll z = e[i].ed;
        if(v[y])continue;
        di[y] = di[x] + z,d[y] = d[x] + 1;
        lca[y][0] = x;
        for(int j = 1;j <= t;j++)
            lca[y][j] = lca[lca[y][j-1]][j-1]; 
        dfs(y);
    }
}
int Lca(int x,int y){
    if(d[x] > d[y])swap(x,y);
    for(int i = t;i >= 0;i--)
        if(d[lca[y][i]] >= d[x])y = lca[y][i];
    if(x == y)return x;
    for(int i = t;i >= 0;i--)
        if(lca[x][i] != lca[y][i])x = lca[x][i],y = lca[y][i];
    return lca[x][0];
}
ll ask(int now,int u){
    int x = now;ll ans = INT_MAX;
    while(d[x] > d[u]){
        ans = min(ans,max(a[x],di[now]-di[x]));
        x = lca[x][0];
    }
    ans = min(ans,max(a[u],di[now]-di[u]));
    return ans;
}
int s;
ll ask1(int now,int u){
    int x = now;ll ans = INT_MAX;
    while(d[x] > d[u]){
        ans = min(ans,max(a[x],s+di[x]-di[u]));
        x = lca[x][0];
    }
    return ans;
}
int main(){
    freopen("poitry.in","r",stdin);
    freopen("poitry.out","w",stdout);
    scanf("%d%d",&n,&q);
    t = int(log2(n))+1;
    for(int i = 1;i <= n;i++)
        scanf("%lld",&a[i]);
    for(int i = 1;i < n;i++){
        int x,y;ll z;
        scanf("%d%d%lld",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    d[1] = 1;
    dfs(1);
    for(int i = 1;i <= q;i++){
        int x,y;s = 0;
        scanf("%d%d",&x,&y);
        int u = Lca(x,y);
        ll ans = ask(x,u);
        s = di[x] - di[u];
        ans = min(ans,ask1(y,u));
        printf("%lld\n",ans);
    }
    
    return 0;
    
}