题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5266
题目就是让你求LCA,模版题。注意dfs会栈溢出,所以要扩栈,或者用bfs写。
1 #pragma comment(linker, "/STACK:102400000,102400000") //扩栈 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 const int MAXN = 3e5 + 5; 7 struct data { 8 int next , to; 9 }edge[MAXN << 1]; 10 int par[MAXN][20] , head[MAXN] , cnt , dep[MAXN]; 11 12 inline void add(int u , int v) { 13 edge[cnt].next = head[u]; 14 edge[cnt].to = v; 15 head[u] = cnt++; 16 } 17 18 void dfs(int u , int d , int p) { 19 dep[u] = d; 20 par[u][0] = p; 21 for(int i = head[u] ; ~i ; i = edge[i].next) { 22 int v = edge[i].to; 23 if(v == p) 24 continue; 25 dfs(v , d + 1 , u); 26 } 27 } 28 29 void init(int n) { 30 for(int k = 0 ; k < 18 ; ++k) { 31 for(int i = 1 ; i <= n ; ++i) { 32 if(par[i][k] <= 0) 33 par[i][k + 1] = par[i][k]; 34 else 35 par[i][k + 1] = par[par[i][k]][k]; 36 } 37 } 38 } 39 40 int lca(int u , int v) { 41 if(dep[u] < dep[v]) 42 swap(u , v); 43 for(int k = 0 ; k < 20 ; ++k) { 44 if(((dep[u] - dep[v]) >> k) & 1) { 45 u = par[u][k]; 46 } 47 } 48 if(u == v) 49 return u; 50 for(int k = 19 ; k >= 0 ; --k) { 51 if(par[u][k] != par[v][k]) { 52 u = par[u][k]; 53 v = par[v][k]; 54 } 55 } 56 return par[u][0]; 57 } 58 59 int main() 60 { 61 int n , q , u , v; 62 while(~scanf("%d" , &n)) { 63 cnt = 0; 64 memset(head , -1 , sizeof(head)); 65 for(int i = 1 ; i < n ; ++i) { 66 scanf("%d %d" , &u , &v); 67 add(u , v); 68 add(v , u); 69 } 70 dfs(1 , 0 , -1); 71 init(n); 72 scanf("%d" , &q); 73 for(int i = 0; i < q; ++i) { 74 scanf("%d %d" , &u , &v); 75 printf("%d\n" , lca(u , v)); 76 } 77 } 78 }
时间: 2024-11-07 09:59:11