zstu_oj4395: 大家+lca求树上a,b两点最短路经过的最大值

题目链接:4395: 大家

题解:平常我们求lca有有数据f[i][v]表示是v往上方走pow(2,i)步的点,我们也可以用mx[i][v]表示是v往上方走pow(2,i)步的点所经过的最大值

转移方程见代码

#include<bits/stdc++.h>
#include<set>
#include<cstdio>
#include<iomanip>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define mk make_pair
#define ll long long
#define fi first
#define se second
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
#define pii pair<int,int>
#define pll pair<ll,ll>
typedef unsigned long long ull;
const int mod=998244353;
const ll inf=0x3f3f3f3f3f3f3f;
const int maxn=2e4+5;
using namespace std;
int n,m,ma,f[20][maxn];
int a[maxn],mx[20][maxn],dep[maxn];
vector<int>g[maxn];
void  dfs(int v,int fa)
{
    for(int i=1;i<20;i++)
    {
       f[i][v]=f[i-1][f[i-1][v]];
        mx[i][v]=max(mx[i-1][f[i-1][v]],mx[i-1][v]);
    }
    for(int i=0;i<g[v].size();i++)
    {
        int to=g[v][i];
        if(to!=fa){
            dep[to]=dep[v]+1;
            f[0][to]=v;
            mx[0][to]=a[v];
            dfs(to,v);
        }
    }
}
int lca(int x,int y)
{
    if(dep[x]<dep[y])swap(x,y);
    int t=dep[x]-dep[y],dx=0,dy=0;
    for(int k=0;k<20;k++)
    {
        if(t>>k&1)
        {
            dx=max(dx,mx[k][x]);x=f[k][x];
        }
    }
    if(x==y)
    {
        ma=dx;return x;
    }
    for(int i=19;i>=0;i--)
    {
        if(f[i][x]!=f[i][y])
        {
            dx=max(dx,mx[i][x]);x=f[i][x];
            dy=max(dy,mx[i][y]);y=f[i][y];
        }
    }
    ma=max(dx,dy);
    ma=max(ma,a[f[0][x]]);
    return f[0][x];
}
int main()
{
     ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i=0;i<n-1;i++)
    {
        int x,y;
        cin>>x>>y;g[x].pb(y);g[y].pb(x);
    }
    for(int j=1;j<=n;j++)cin>>a[j];
    dfs(1,0);
    while(m--)
    {
        int x,y;
        cin>>x>>y;ma=0;
        if(dep[x]<dep[y])swap(x,y);
        if(x==y)
        {
           cout<<a[x]<<endl;
        }
        else if(lca(x,y)!=y)
        {
            cout<<-1<<endl;
        }
        else
        {
            cout<<max(ma,a[x])<<endl;
        }
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/lhclqslove/p/9301511.html
今日推荐