zoukankan      html  css  js  c++  java
  • HDU3078 Network (倍增LCA算法求树链)

    题意:

    一棵无向树,输入点数和操作数,下面一行n个值代表每个点的权。下面n-1行是树边 操作分为 0 x w ,表示把点x的权改为w; k a b , 求出,从a到b的路径中,第k大的点权

    题解:

    对于每组询问,先求出两点的LCA,再从两点分别向LCA遍历,保存路径上所有的点权,排序输出第K大即可~

    #include<cstdio>
    #include<algorithm>
    #include<cstring> 
    #include<vector>
    using namespace std;
    const int maxn=1e5+10;
    int N,M,Q;
    int t[maxn];
    int cnt=0;
    int head[maxn];
    int tol;
    struct node {
        int u;
        int v;
        int w;
        int next;
    }edge[maxn*2];
    void addedge (int u,int v) {
        edge[tol].u=u;
        edge[tol].v=v;
        edge[tol].next=head[u];
        head[u]=tol++;
    }
    int weight[maxn];
    int d[maxn];
    int h[maxn];
    int father[20][maxn];
    void dfs (int x) {
        for (int i=head[x];i!=-1;i=edge[i].next) {
            int v=edge[i].v;
            if (v==father[0][x]) continue;
            father[0][v]=x;
            h[v]=h[x]+1;
            dfs(v);
        }
    }
    int lca (int x,int y) {
        if (h[x]<h[y]) swap(x,y);
        for (int i=17;i>=0;i--) 
            if (h[x]-h[y]>>i) x=father[i][x];
        if (x==y) return x;
        for (int i=17;i>=0;i--) {
            if (father[i][x]!=father[i][y]) {
                x=father[i][x];
                y=father[i][y];
            }
        }
        return father[0][x];
    }
    int main () {
        scanf("%d%d",&N,&Q);
        memset(head,-1,sizeof(head));
        for (int i=1;i<=N;i++) 
            scanf("%d",&weight[i]);
        for (int i=0;i<N-1;i++) {
            int u,v;
            scanf("%d%d",&u,&v);
            addedge(u,v);
            addedge(v,u);
        }
        dfs(1);
        for (int i=1;i<=17;i++) 
            for (int j=1;j<=N;j++)
                father[i][j]=father[i-1][father[i-1][j]];
        for (int i=0;i<Q;i++) {
            int k,x,y;
            scanf("%d%d%d",&k,&x,&y);
            if (k==0) weight[x]=y;
            else {
                int r=lca(x,y);
                cnt=0;
                while (x!=r) {
                    t[cnt++]=weight[x];
                    x=father[0][x];
                }
                while (y!=r) {
                    t[cnt++]=weight[y];
                    y=father[0][y];
                }
                t[cnt++]=weight[r];
                sort(t,t+cnt);
                if (cnt<k) {
                    printf("invalid request!
    ");
                    continue;
                } 
                printf("%d
    ",t[cnt-k]);
            }
        }
    }
  • 相关阅读:
    C# 实现list=list.OrderBy(q=>q.字段名).ToList(); 按多个字段排序
    c# dev gridcontrol 焦点行失去焦点有背景颜色
    c# dev gridcontrol format rule的使用
    鼠标模拟左键单击
    IDEA快捷键/本文仅供自己参考使用如有侵权立删
    Git学习笔记
    bootstrap帮助文档
    bootstrap笔记
    关于Action模型驱动无法获取属性的问题
    SSH整合hibernate无法正常自动生成表
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12527160.html
Copyright © 2011-2022 走看看