首页 > 代码库 > Poj1330Nearest Common Ancestors LCA
Poj1330Nearest Common Ancestors LCA
题意给一颗树,再给一个查询两点之间的最近公共祖先。
#include<iostream>#include<cstdio>#include<cstring>#include<map>#include<vector>using namespace std;const int maxn = 111111;struct edge{ int to; int next;}e[maxn * 10];int len;int head[maxn];struct Node{ int val; int id;}vis[maxn], dp[maxn][20];int pos[maxn];int cnt;void add(int from, int to){ e[len].to = to; e[len].next = head[from]; head[from] = len++;}void dfs(int x, int val){ vis[cnt].val = val; vis[cnt].id = x; pos[x] = cnt++; for (int i = head[x]; i != -1; i = e[i].next){ int cc = e[i].to; dfs(cc, val + 1); vis[cnt].val = val; vis[cnt].id = x; pos[x] = cnt++; }}void init(int k){ for (int i = 0; i < k; i++) dp[i][0] = vis[i]; for (int j = 1; (1 << j) <= k; j++){ for (int i = 0; i + (1 << j) - 1 < k; i++){ if (dp[i][j - 1].val < dp[i + (1 << (j - 1))][j - 1].val) dp[i][j] = dp[i][j - 1]; else dp[i][j] = dp[i + (1 << (j - 1))][j - 1]; } }}int ask(int l, int r){ int k = 0; while ((1 << (k + 1)) < r - l + 1) k++; if (dp[l][k].val < dp[r - (1 << k) + 1][k].val) return dp[l][k].id; else return dp[r - (1 << k) + 1][k].id;}int main(){ int T; int n; cin >> T; int root; int gg[maxn]; int a, b; while (T--){ cin >> n; len = 0; memset(head, -1, sizeof(head)); for (int i = 1; i <= n; i++) gg[i] = 0; for (int i = 0; i<n - 1; i++){ scanf("%d%d", &a, &b); add(a, b); gg[b] = 1; } for (int i = 1; i <= n; i++) if (!gg[i]) { root = i; break; } cnt = 0; dfs(root, 1); init(cnt); cin >> a >> b; int l = pos[a]; int r = pos[b]; if (l>r) swap(l, r); cout << ask(l, r) << endl; } return 0;}
Poj1330Nearest Common Ancestors LCA
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。