zoukankan      html  css  js  c++  java
  • hdu6031 Innumerable Ancestors

    hdu6031 Innumerable Ancestors
    倍增
    题意
    给定一张无向图,对于每组询问,给出两个集合 A 与 B
    求 lca(x,y) 最深的时候的深度 x属于A y属于B

    题解
    首先 我们发现答案具有单调性,于是我们就可以二分这个答案 mid
    然后 把 a 集合 的 这个深度的祖先 求出来 然后看 与b 集合的这个深度 祖先 是否有交集就行了
    用set 判断 是否有交集
    用倍增法 快速求出一个点的祖先 求一次 只要 log n

      1 #include <bits/stdc++.h> 
      2 #define ll long long  
      3 #define cl(a,b) memset(a,b,sizeof(a)) 
      4 using namespace std ;  
      5 
      6 const int N = 1e5 + 11 ; 
      7 struct Edge{
      8     int to,pre ; 
      9 }e[N*2] ; 
     10 int n,Q,cnt,k1,k2,ans,l,r ; 
     11 int head[N],deep[N],anc[N][21],a[N],b[N] ;   
     12 
     13 inline int read() 
     14 {
     15     int x = 0 , f = 1 ; 
     16     char ch = getchar() ; 
     17     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ; } 
     18     while(ch>='0'&&ch<='9') { x = x * 10+ch-48 ; ch = getchar() ; } 
     19     return x * f ; 
     20 }
     21 
     22 inline void add(int x,int y) 
     23 {
     24     e[++cnt].to = y ; 
     25     e[cnt].pre = head[x] ; 
     26     head[x] = cnt ; 
     27 }
     28 
     29 inline void init()  
     30 {
     31     cl( head,-1 ) ;
     32     cl( deep,0 ) ;  
     33     cl( anc,-1 ) ; 
     34     cnt = 0 ; 
     35 }
     36 
     37 inline void dfs(int u,int fa,int d) 
     38 {
     39     deep[ u ] = d ; 
     40     for(int i=head[u]; ~i ; i = e[i].pre)
     41     {
     42         int v = e[ i ].to ; 
     43         if(v==fa) continue ; 
     44         anc[ v ][ 0 ] = u ; 
     45         dfs(v,u,d+1) ; 
     46     }
     47 }
     48 
     49 inline void lca_init() 
     50 {
     51     for(int j=1; (1<<j) <= n ; j++) 
     52         for( int i=1;i<=n;i++ ) 
     53             if(anc[i][j-1]!=-1) 
     54                 anc[i][j] = anc[anc[i][j-1]][j-1] ; 
     55 }
     56 
     57 inline int query(int u,int d) 
     58 //  返回  u的 第 d 个父亲 
     59 {
     60     if( d < 0 ) return -1 ; 
     61     if( d==0 ) return u ; 
     62     int i ; 
     63     for(i=0; (1<<i) <= d ;i++) ;   //  注意 这里有分号相当于 求 log  没有的话 死循环  
     64     i-- ; 
     65     for( ;i>=0;i--)
     66         if(d-(1<<i) >= 0) 
     67         {
     68             d-=(1<<i) ; 
     69             u = anc[u][i] ; 
     70         } 
     71     return u ; 
     72 } 
     73 
     74 inline bool check(int x) 
     75 {
     76     set<int>s ; 
     77     for(int i=1;i<=k1;i++) 
     78     {
     79         int dis = deep[a[ i ]] - x ; 
     80         int ret = query(a[ i ],dis) ; 
     81         if(ret==-1) continue ; 
     82         s.insert(ret) ; 
     83     }
     84     for(int i=1;i<=k2;i++) 
     85     {
     86         int dis = deep[b[ i ]] - x ; 
     87         int ret = query( b[ i ],dis ) ; 
     88         if(s.count(ret)) return true ;   
     89     }
     90     return false ; 
     91 }
     92 
     93 int main() 
     94 { 
     95     while(~scanf("%d%d",&n,&Q)) 
     96     {
     97         init() ; 
     98         int x,y ; 
     99         for(int i=1;i<n;i++) 
    100         {
    101             scanf("%d%d",&x,&y) ; 
    102             add(x,y) ; add(y,x) ; 
    103         }
    104         dfs(1,1,1) ; 
    105         lca_init() ; 
    106         
    107         while(Q--) 
    108         {
    109             scanf("%d",&k1) ; 
    110             l = 1 ; r = 1 ; 
    111             for(int i=1;i<=k1;i++) 
    112                 scanf("%d",&a[ i ]),r = max(r,deep[ a[ i ] ]) ; 
    113             scanf("%d",&k2) ; 
    114             for(int i=1;i<=k2;i++) 
    115                 scanf("%d",&b[ i ]) ;  
    116             while(l<=r) 
    117             {
    118                 int mid = ( l+r ) >>1 ; 
    119                 if(check(mid)) 
    120                 {
    121                     ans = mid ; 
    122                     l = mid + 1 ; 
    123                 }
    124                 else 
    125                     r = mid - 1 ; 
    126             } 
    127             printf("%d
    ",ans ) ; 
    128         }
    129     }
    130     
    131     return 0 ; 
    132 }
  • 相关阅读:
    wget(转)
    852. Peak Index in a Mountain Array
    617. Merge Two Binary Trees
    814. Binary Tree Pruning
    657. Judge Route Circle
    861. Score After Flipping Matrix
    832. Flipping an Image
    461. Hamming Distance
    654. Maximum Binary Tree
    804. Unique Morse Code Words
  • 原文地址:https://www.cnblogs.com/third2333/p/7126846.html
Copyright © 2011-2022 走看看