zoukankan      html  css  js  c++  java
  • hdu3078 建层次树+在线LCA算法+排序

    题意:n个点,n-1条边构成无向树,每个节点有权,Q次询问,每次或问从a->b的最短路中,权第k大的值,/或者更新节点a的权,
    思路:在线LCA,先dfs生成树0,标记出层数和fa[](每个节点的父亲节点)。在对每次询问,走一遍一次公共祖先路上

    的权,保持,快排。n*logn*q


    #include<iostream>  //187MS 
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    using namespace std;
    int n,q;
    int w[90000];
    vector<vector<int> >e(160100);
    int lev[80010];int vis[80010];
    int fa[80010];
    void dfs_getlev(int u)       //dfs
    {
        for(int i=0;i<e[u].size();i++)
        {
            int v=e[u][i];
            if(!vis[v])
            {
                vis[v]=1;
                lev[v]=lev[u]+1;
                fa[v]=u;
                dfs_getlev(v);
            }
        }
    }
    bool my(int a,int b)
    {
         return a>b;
    }
    int find_lca(int k,int a,int b)   //在线lca,按层次向上走。
    {
        vector<int> ans;
        if(lev[a]>lev[b])
        {
            int temp=a;a=b;b=temp;
        }
        while(lev[b]>lev[a])
        {
            ans.push_back(w[b]);
            b=fa[b];
        }
        while(a!=b)
        {
            ans.push_back(w[b]);
            ans.push_back(w[a]);
            a=fa[a];
            b=fa[b];
        }
         ans.push_back(w[b]);
       if(k>ans.size()) return -1;
       sort(ans.begin(),ans.end(),my);
       return   ans[k-1];
    }
    int main()
    {
        cin>>n>>q;
        for(int i=1;i<=n;i++)
            scanf("%d",&w[i]);
        int ta,tb;
        for(int i=0;i<n-1;i++)
        {
              scanf("%d%d",&ta,&tb);
              e[ta].push_back(tb);
              e[tb].push_back(ta);
        }
        vis[1]=lev[1]=1;
        dfs_getlev(1);
        int k,a,b;
        while(q--)
        {
            scanf("%d%d%d",&k,&a,&b);
            if(k>0)
            {
                int anss =find_lca(k,a,b);
                if(anss!=-1)
                  printf("%d
    ",anss);
                else
                  printf("invalid request!
    ");
            }
            else
            {
                w[a]=b;
            }
        }
        return 0;
    }
    


  • 相关阅读:
    Java抓取网页数据(原网页+Javascript返回数据)
    Android Bundle类
    【设计模式】命令模式
    oracle触发器实例
    各大名企笔试及面经大全(程序猿必读)
    数据库索引的作用和长处缺点
    一个int类型究竟占多少个字节
    如何遮挡电影英汉字幕
    如何重启mysql服务
    修改mysql默认字符集的方法
  • 原文地址:https://www.cnblogs.com/yezekun/p/3925716.html
Copyright © 2011-2022 走看看