POJ-1330 Nearest Common Ancestors(lca模板题)

来源:互联网 发布:如何编写js插件 编辑:程序博客网 时间:2024/06/04 18:23

题意:

给定树形图,给定两点,求两点的最近公共祖先。

模板:

#include <algorithm>#include <string.h>#include <vector>#include <cstdio>#include <cmath> using namespace std;const int maxn = 1e4+5;int t, n, u, v;vector<int> g[maxn];int E[2*maxn], cnt;int R[maxn], dep[maxn];int f[2*maxn][20];int vis[maxn];void dfs(int u, int fa, int depth){E[++cnt] = u;R[u] = cnt, dep[u] = depth;for(int i = 0; i < g[u].size(); ++i){int v = g[u][i];if(v == fa) continue;dfs(v, u, depth+1);E[++cnt] = u;}}void rmq_init(int n){for(int i = 1; i <= n; ++i) f[i][0] = E[i];for(int j = 1; (1<<j) <= n; ++j)for(int i = 1; i+(1<<j)-1 <= n; ++i){int a = f[i][j-1], b = f[i+(1<<(j-1))][j-1];f[i][j] = dep[a] < dep[b]? a: b;}}int rmq(int l, int r){int k = log2(r-l+1);int a = f[l][k], b = f[r-(1<<k)+1][k];return dep[a] < dep[b]? a: b;}int lca(int u, int v){int l = R[u], r = R[v];if(l > r) swap(l, r);return rmq(l, r);}void init(){for(int i = 1; i <= n; ++i) g[i].clear();cnt = 0;memset(vis, 0, sizeof vis);}int main(){for(scanf("%d", &t); t--;){scanf("%d", &n); init();for(int i = 1; i < n; ++i){scanf("%d %d", &u, &v);g[u].push_back(v);vis[v] = 1;}scanf("%d %d", &u, &v);for(int i = 1; i <= n; ++i)if(!vis[i]){dfs(i, i, 1);break;}rmq_init(cnt);printf("%d\n", lca(u, v));}return 0;}


继续加油~

原创粉丝点击