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]);
            }
        }
    }
  • 相关阅读:
    [Angular] How to show global loading spinner for application between page navigation
    [NgRx] NgRx Data Fetching Solution
    [NgRx] NgRx Entity Adapter Configuration
    [Javascript] Construct a Regex to Match Twitter Mentions with Regexr
    [Dart] Dynamic variable in Dart
    [NgRx] NgRx Runtime Checks
    [NgRx] Setting up NgRx Router Store and the Time-Travelling Debugger
    浅析数据库设计三范式
    建议别买三星Gear:半电脑产品 设计糟糕
    持续集成理论和实践的新进展
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12527160.html
Copyright © 2011-2022 走看看