首页 > 代码库 > poj 1330 Nearest Common Ancestors (LCA)
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)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。