zoukankan      html  css  js  c++  java
  • [10.2模拟] tree

    题意:给你一棵树,m次询问,每次询问(a,b),即a和b是否在一条链上

    题解:

    树上倍增

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define RG register
    #define N 200010
    using namespace std;
    
    int n,qu,e_num;
    int nxt[N*2],to[N*2],h[N],siz[N],dep[N],fa[N][22];
    
    inline int gi() {
      int x=0,o=1; char ch=getchar();
      while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
      if(ch=='-') o=-1,ch=getchar();
      while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
      return o*x;
    }
    
    inline void add(int x, int y) {
      nxt[++e_num]=h[x],to[e_num]=y,h[x]=e_num;
    }
    
    inline int find(int y, int x) {
      for(int j=20; j>=0; j--) {
        if(dep[fa[y][j]]>dep[x] && fa[y][j]) y=fa[y][j];
      }
      return y;
    }
    
    inline void dfs(int u) {
      siz[u]=1;
      for(int i=h[u]; i; i=nxt[i]) {
        int v=to[i];
        if(v==fa[u][0]) continue;
        fa[v][0]=u,dep[v]=dep[u]+1;
        dfs(v);
        siz[u]+=siz[v];
      }
    }
    
    int main() {
      n=gi(),qu=gi();
      for(RG int i=1; i<n; i++) {
        int x=gi(),y=gi();
        add(x,y),add(y,x);
      }
      dep[1]=1;
      dfs(1);
      for(int j=1; j<=20; j++)
        for(int i=1; i<=n; i++)
          fa[i][j]=fa[fa[i][j-1]][j-1];
      for(int i=1; i<=qu; i++) {
        int x=gi(),y=gi(),z;
        if(dep[x]>dep[y]) swap(x,y);
        z=find(y,x);
        if(fa[z][0]!=x) printf("%d
    ", siz[x]+siz[y]);
        else printf("%d
    ", siz[y]+n-siz[z]);
      }
      return 0;
    }
    
    
  • 相关阅读:
    上传文件过大的问题FileUploadBase$SizeLimitExceededException
    Oracle分页2
    详解struts2中struts.properties
    Oracle 分页
    Xcode常见错误以及解决方案
    设置时间格式
    UIScrollView解决touchesBegan等方法不能触发的解方案
    ViewController 之间设置转场动画
    IQKeyboredManager使用
    SVN
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7625197.html
Copyright © 2011-2022 走看看