poj 1330 Nearest Common Ancestors (LCA)
Posted gccbuaa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 1330 Nearest Common Ancestors (LCA)相关的知识,希望对你有一定的参考价值。
题意:求两个点的近期公共祖先。
1A
#include<cstdio> #include<iostream> #include<cstring> #include<vector> #define maxn 100010 using namespace std; int fa[maxn],lev[maxn],pre[maxn],c1,c2; vector<int> son[maxn]; bool dfs(int rt,int obj) { for(int i=0;i<son[rt].size();i++) { int t = son[rt][i]; pre[t] = rt; lev[t] = lev[rt]+1; if(t!=obj) { if(dfs(t,obj)) return true; } else return true; } return false; } void solve(int rt) { memset(lev,0,sizeof(lev)); dfs(rt,c1); dfs(rt,c2); pre[rt] = -1; int x,y; if(lev[c1]>=lev[c2]) { x = c1; y = c2; } else { x = c2; y = c1; } while(lev[x]!=lev[y]) x = pre[x]; if(x==y) printf("%d\n",y); else { int k,l; for(k=pre[x],l=pre[y];k!=l;k=pre[k],l=pre[l]); printf("%d\n",k); } } int main() { int T,n,a,b,rt; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) { fa[i] = i; son[i].clear(); } for(int i=1;i<n;i++) { scanf("%d%d",&a,&b); son[a].push_back(b); fa[b] = a; } scanf("%d%d",&c1,&c2); for(int i=1;i<=n;i++) { if(fa[i]==i) { rt = i; break; } } solve(rt); } return 0; }
tarjan离线LCA算法
算法流程:
Tarjan(u)
F(u)<-u;
For each (u,v) in Q(u) do Answer(u,v) <- F(v)
For each v in son(u)
a) Tarjan(v)。
b) F(v) <- u。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #define maxn 100010 using namespace std; int fa[maxn],anc[maxn],n,f,s,in[maxn]; bool vis[maxn]; vector<int> G[maxn]; void set_(int m) { fa[m] = m; } int root(int x) //带路径压缩的查找函数 { if(fa[x]==x) return x; else fa[x] = root(fa[x]); return fa[x]; } void merge_(int a,int b) { int fx = root(a); int fy = root(b); if(fx!=fy) fa[fy] = fx; } void LCA(int u) //tarjan离线算法 { set_(u); vis[u] = true; if(u==s && vis[f]) { printf("%d\n",root(f)); return; } if(u==f && vis[s]) { printf("%d\n",root(s)); return ; } for(int i=0;i<G[u].size();i++) { int v = G[u][i]; if(!vis[v]) { LCA(v); fa[v] = u; } } } int main() { int T,a,b; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) { G[i].clear(); in[i] = 0; } for(int i=1;i<n;i++) { scanf("%d%d",&a,&b); G[a].push_back(b); in[b]++; //统计入度,由于有根树根不同找到的LCA也不同 } memset(vis,0,sizeof(vis)); scanf("%d%d",&f,&s); int rt; for(int i=1;i<=n;i++) { if(!in[i]) { rt = i; break; } } LCA(rt); } return 0; }
以上是关于poj 1330 Nearest Common Ancestors (LCA)的主要内容,如果未能解决你的问题,请参考以下文章
poj1330 Nearest Common Ancestors
[POJ1330]Nearest Common Ancestors(LCA, 离线tarjan)
POJ 1330 Nearest Common AncestorsLCA Tarjan算法
POJ 1330 Nearest Common Ancestors (最近公共祖先LCA + 详解博客)