Codeforces 라운드 # 629 (사업부. 3) E. 트리 쿼리 (LCA)

https://codeforces.com/contest/1328/problem/E

설명 주제는 문제는 루트 노드로 표현 된, 나무입니다.

이보다 적은 K 점의 세트로부터 경로가 존재하는지의 경로를 만족 한 경우와 동일 질문이 전환 될 수 있는가?

아이디어 :

1. 우선, 예비 승산 접합 깊이 오프라인 온라인 후속 질의를 촉진 LCA

각 문의 2. 순차 K 포인트 스캔. 지점의 수집을위한 U 및 V 우리는 u 및 LCA의 V를 얻을 때마다, U 및 V는 LCA의 거리를 계산되면, LCA는 동시 U와 V의 거리가되도록, 다음 경로를 찾을 수 없다는 1보다 크면 U 및 V는 체인 통로 (1) 이하의 거리이다.

3. 어떻게 K 포인트를 확인하기 위해? 분지 그러한 탐욕 다운 최적이어야 각 체크 포인트를 상기 LCA U로부터 거리 지점 V에 따라, 상기 다음 노드와 상기 질의에 가장 먼 점까지의 LCA 비교한다.

1 #INCLUDE <비트 / stdc ++ H.>
 2  사용  공간은 수 std;
3  CONST  INT maxn 2E5 + = 500 ;
4  CONST  INT maxbit = 18 ;
5 벡터 < INT > g [maxn];
6  INT DEP [maxn];
7  INT FA [maxn] maxbit];
8  INT 로그 [maxn];
9  INT N;
10 타입 정의  LL;
(11)  보이드 추가 ( int로 , U를 INT V)를 {
12      g [U] .push_back (V) g [V] .push_back (U)를;
(13)  }
 (14)  보이드 프리 () {
 15      로그인 [ 0 ] = - 1 ;
16      로그 [ 1 ] = 0 , 로그인 [ 2 ] = 1 ;
17       ( INT가 나는 = 3 ; I <maxn; I ++) 로그인 [I] = 로그 [I / 2 ] + 1 ;
18  }
 19  무효 DFS ( INT의 CUR, INT 아버지) {
 20      DEP [CUR = DEP [아버지] + 1 ;
(21)     FA [CUR] [ 0 ] = 아버지;
22       ( INT J = 1 ( 1 << j)는 <= N; J ++ ) {
 23          FA [CUR] [J] = FA [FA [CUR] [J = 1 ] [J = 1 ];
24      }
 25       ( 하는 int 전 = 0 ; I <g [CUR] 크기는 (); I ++ ) {
 26 일          경우 (! g을 [CUR [I] = 아버지) {
 27              DFS (g [CUR [I], 똥개);
28          }
 29      }
 30  }
 31  INT의 LCA ( INTU, INT V) {
 32      의 경우 (DEP [U] < 출발 [V]) 스왑 (U, V);
33      INT DIST = DEP [U] - 출발 [V];
34      동안 (DEP [유]! = DEP [V]) {
 35          U = FA [U]가 [로그인 [DEP [유] - DEP [V]];
36      }
 37      의 경우 (U == V) 복귀 U 단계;
(38)      에 대한이 ( INT는 , I> = 1 로그 [DEP를 [U] = 0 ; 난 - {)
 (39)          의 경우 (! FA [U] [I] = FA [V] [I]) {
 40              U = FA [ U] [I];
(41)              V = FA [V] [I];
42          }
 43      }
 44      리턴 FA [U] [ 0 ];
45  }
 46  INT의 주 () {
 47      INT에서 Q;
48      는 scanf ( " % D % D " , N, Q);
49       ( INT 난 = 1 ; 나는 <N; I ++ ) {
 50          INT U, V는;
51          는 scanf ( " % D % D ' , U, 및 V);
(52)          추가 (U, V);
53      }
 54      사전 ();
(55)     (DFS . 1 , 0 ),
 (56)이      그동안 (Q - ) {
 57는          INT K]는 scanf ( " %의 D ' , K)
 58          BOOL F = 0 ;
 59          INT T [K + . 1 ]
 60           ( INT I = . (1) , I <= K; I ++)는 scanf ( " %의 D " , 및 T [I]);
 (61)는          INT V = T [ 1이다. ]; // 전류 대비 포인트가 설정되어있는 V로 
62          위해 ( INT I = 2; I <= K; I ++ ) {
 63는              INT LCA = 전과정 (V, T [I]);
 (64)              IF (ABS (DEP [T [I] - DEP [LCA])> . (1 개) && ABS (DEP [V] -dep [LCA])> 1 ) {
 65                  F = 1 ; // LCA 거리가 동시에 1 이상이 발생하면이 문제 트리 체인의 의미 만족하는 것으로되어서는 안 
66                  BREAK ;
 67              }
 68              ABS (DEP [T를 [I] -dep [LCA])> ABS (DEP [V] -dep [LCA]) = V t [i]는 :? V = V;         // 경우 t [I]는 LCA 장거리에 V 넣어 업데이트 될 t [i]는, 다음의 점에 비하여 그리.    
69          }
 70          IF COUT << (! F) " YES " << ENDL;
 71 IS         다른 COUT << " NO " << ENDL;
72      }
 73      반환  0 ;
74  }
 75  / * 
76  8
 77  13 13 9 12 13 13 1 1
 78  * /

 

추천

출처www.cnblogs.com/AaronChang/p/12590348.html