RMQ求LCA模板:
//#pragma comment(linker,"/STACK:327680000,327680000") #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 150 #define N 10007 using namespace std; struct node { int v,w; int next; }g[N]; int head[N],ct; int vNum[2*N],fNum[N],depth[2*N]; int cnt; int dp[2*N][20]; int pow2[20],ind[N]; bool vt[N]; int n; void init() { cnt = 0; CL(head,-1); CL(ind,0); ct = 0; } void add(int u,int v) { g[ct].v = v; g[ct].next = head[u]; head[u] = ct++; } void dfs(int u,int dep) { vt[u] = true; vNum[cnt] = u;//记录dfs的每个节点 depth[cnt] = dep;//记录dfs每个节点的深度 fNum[u] = cnt;//记录每节点第一次出现的编号 cnt++; for (int i = head[u]; i != -1; i = g[i].next) { int v = g[i].v; if (!vt[v]) { dfs(v,dep + 1); vNum[cnt] = u; depth[cnt] = dep; cnt++; } } } int imin(int i,int j) { if (depth[i] < depth[j]) return i; else return j; } void init_rmq() { int i,j; for (i = 0; i < cnt; ++i) dp[i][0] = i; for (j = 1; pow2[j] <= cnt; ++j) { for (i = 0; i + pow2[j] - 1 < cnt; ++i) { dp[i][j] = imin(dp[i][j - 1],dp[i + pow2[j - 1]][j - 1]); } } } int rmq(int l,int r) { int k = (int)(log(1.0*(r - l + 1))/log(2.0)); return imin(dp[l][k],dp[r - pow2[k] + 1][k]); } int main() { int i,T; int x,y; for (i = 0; i <= 20; ++i) pow2[i] = 1<<i; scanf("%d",&T); while (T--) { scanf("%d",&n); init(); for (i = 0; i < n - 1; ++i)//n-1条边 { scanf("%d%d",&x,&y); ind[y]++;//统计每个节点入度找出根节点 add(x,y); } //找根节点 int root = 0; for (i = 1; i <= n; ++i) { if (ind[i] == 0) { root = i; break; } } //dfs给每一个节点编号,并且记录深度 CL(vt,false); dfs(root,0); //rmq处理 init_rmq(); scanf("%d%d",&x,&y); if (fNum[x] <= fNum[y]) printf("%d\n",vNum[rmq(fNum[x],fNum[y])]); else printf("%d\n",vNum[rmq(fNum[y],fNum[x])]); } return 0; }