zoukankan      html  css  js  c++  java
  • hdu1762 树的上的查询


    2015-10-07 20:44:42


    题意问的是给了一颗树,然后又1000000次查询u,v,问不在树路径上的点的编号最小值,以1为根 建这颗树,然后在同一棵子树中的点子让就输出1 否则我们记录每个点从离1最近的那个点也就是1的孩子,到该点所经过的最小值,以及在他父亲到1的孩子,这段间和他不在同一条叉到上的最小值,还有就是他子树的最小值,然后遍历一遍,每次查询的时候搞一下就好了

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <string.h>
    using namespace std;
    const int maxn=1000005;
    template <class T>
    inline bool rd(T &ret) {
        char c; int sgn;
        if (c = getchar(), c == EOF) return 0;
        while (c != '-' && (c<'0' || c>'9')) c = getchar();
        sgn = (c == '-') ? -1 : 1;
        ret = (c == '-') ? 0 : (c - '0');
        while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return 1;
    }
    template <class T>
    inline void pt(T x) {
        if (x <0) {
            putchar('-');
            x = -x;
        }
        if (x>9) pt(x / 10);
        putchar(x % 10 + '0');
    }
    int fa[maxn],H[maxn],to[maxn*2],nx[maxn*2],numofE;
    int upMIN[maxn],downMIN[maxn][2],other[maxn];
    int belong[maxn];
    
    void init(int N){
      numofE=0;
      memset(H,0,sizeof(H));
    }
    void add(int u,int v)
    {
        numofE++;
        to[numofE]=v;
        nx[numofE]=H[u];
        H[u]=numofE;
    }
    int Q[maxn];
    void cmp(int O,int a){
       if(a<downMIN[O][0]){
          downMIN[O][1]=downMIN[O][0];
          downMIN[O][0]=a;
       }else if(a<downMIN[O][1]){
          downMIN[O][1]=a;
       }
    }
    void searchroot(int cur)
    {
         int rear=0;
         Q[rear++]=cur;
         fa[cur]=1;
         belong[cur]=cur;
         upMIN[cur]=cur;
         for(int i=0; i<rear; i++)
         {
             int x=Q[i];
             other[x]=downMIN[x][0]=downMIN[x][1]=maxn;
             for(int j=H[x]; j; j=nx[j])
             {
                 int too=to[j];
                 if(too==fa[x])continue;
                 Q[rear++]=too;
                 fa[too]=x;
                 upMIN[too]=min(too,upMIN[x]);
                 belong[too]=cur;
             }
         }
         for(int i=rear-1; i>=0; i--)
         {
             int x=Q[i];
             for(int j=H[x]; j; j=nx[j])
             {
                 int too=to[j];
                 if(too==fa[x])continue;
                 int a=min(too,downMIN[too][0]);
                 cmp(x,a);
             }
         }
    
         for(int i=1; i<rear; i++){
             int x=Q[i];
             int a=min(x,downMIN[x][0]);
             int f=fa[x];
             if(a!=downMIN[f][0]){
                other[x]=min(other[f],downMIN[f][0]);
             }else{
                other[x]=min(other[f],downMIN[f][1]);
             }
         }
    }
    int A[4],B[5];
    void jud(int a)
    {
        A[3]=a;
        for(int i=2; i>=0; i--)
            if(A[i]>A[i+1])swap(A[i],A[i+1]);
            else break;
    }
    void solve1(int a,int b)
    {
        for(int i=0; i<3; i++)
        if(A[i]!=a&&A[i]!=b){
            B[0]=A[i];return ;
        }
    }
    int jud2()
    {
        int v=B[0];
        for(int i=1;i<5;i++)
            v=min(B[i],v);
        return v;
    }
    
    int main()
    {
        int N,q;
        downMIN[1][0]=downMIN[1][1]=other[1]=upMIN[1]=maxn;
        while(scanf("%d%d",&N,&q)==2)
        {
           init(N);
           for(int i=1; i<N; i++)
           {
               int a,b;
               rd(a);rd(b);
    
               add(a,b);add(b,a);
           }
           A[0]=A[1]=A[2]=maxn;
           for(int i=H[1]; i; i=nx[i])
            {
                searchroot(to[i]);
                jud(min(to[i],downMIN[to[i]][0]));
            }
            int d=0;
           for(int i=0; i<q; i++)
           {
               int a,b;
               rd(a);rd(b);
               a^=d;b^=d;
               if(a==1&&b==1){
                 d=2;
                 puts("2");continue;
               }
               if(belong[a]==belong[b]){
                   d=1;
                   puts("1");continue;
               }
               if(a==1||b==1){
                  a=max(a,b);b=max(a,b);
               }
               solve1(upMIN[a],upMIN[b]);
               B[1]=other[a];B[2]=other[b];
               B[3]=downMIN[a][0];B[4]=downMIN[b][0];
               d=jud2();
               printf("%d
    ",d);
            }
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    被 5 整除的数
    天才的主意
    天才的主意
    谷歌浏览器 —— 快捷键(vimium:像使用 vim 一样操作当前页面)
    谷歌浏览器 —— 快捷键(vimium:像使用 vim 一样操作当前页面)
    膨胀和腐蚀操作中的不同结构元效果对比
    水果的辨异
    水果的辨异
    推理集 —— 特殊与差异
    推理集 —— 特殊与差异
  • 原文地址:https://www.cnblogs.com/Opaser/p/4859448.html
Copyright © 2011-2022 走看看