zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    vim 查找文件指定内容所在位置
    tar 使用小技巧
    dpkg 安装deb包
    Jetbrains 全家桶(IDEA,PyCharm...)
    Python如何生成requirements.txt文件
    MySQL——导入数据报字段编码错误
    视图的概念、作用以及如何创建
    hive与hbase及MySQL的区别
    mysql—排序函数rank() over()、dense_rank() over()、row_num() over()
    mysql —net start mysql 命令发生系统错误5和错误1058的解决方法
  • 原文地址:https://www.cnblogs.com/lhclqslove/p/9301511.html
Copyright © 2011-2022 走看看