LCA最近公共祖先(RMQ、Tarjan)
来源:互联网 发布:cda数据分析师难嘛 编辑:程序博客网 时间:2024/06/05 05:07
题目:http://poj.org/problem?id=1330
讲解:http://blog.csdn.net/tingyun_say/article/details/52092464
离线算法:dfs+并查集(Tarjan)
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<vector>using namespace std;const int N=1e4+107;const int inf=0x3f3f3f3f;int n,q1,q2;int f[N],a[N];bool c[N],flag[N];vector<int> v[N];int find(int k){ if(f[k]==k) return k; f[k]=find(f[k]); return f[k];}int unions(int x,int y){ int xx=find(x),yy=find(y); f[yy]=xx; return 0;}int tarjan(int u){ for(int i=0;i<v[u].size();i++) { tarjan(v[u][i]); unions(u,v[u][i]); a[find(u)]=u; } c[u]=1; if(q1==u&&c[q2]) printf("%d\n",a[find(q2)]); else if(q2==u&&c[q1]) printf("%d\n",a[find(q1)]); return 0;}int main(){ int t,i; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1;i<=n;i++) { v[i].clear(); f[i]=i; a[i]=0; c[i]=0; flag[i]=1; } for(i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); flag[y]=0; v[x].push_back(y); } scanf("%d%d",&q1,&q2); for(i=1;i<=n;i++) if(flag[i]) break; tarjan(i); } return 0;}在线算法:dfs+RMQ(RMQ)
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<vector>using namespace std;const int N=1e4+107;const int inf=0x3f3f3f3f;const int log=20;int dp[N][log],depth[N],deg[N];struct node{ int to; node *next;}g[2*N],*cur,*head[N];void addnode(int u,int v){ cur->to=v; cur->next=head[u]; head[u]=cur++;}void dfs(int u){ depth[u]=depth[dp[u][0]]+1; for(int i=1;i<log;i++) dp[u][i]=dp[dp[u][i-1]][i-1]; for(node *it=head[u];it;it=it->next) dfs(it->to);}int lca(int u,int v){ if(depth[u]<depth[v]) swap(u,v); for(int st=1<<(log-1),i=log-1; i>=0 ;i--,st>>=1) if(st<=depth[u]-depth[v]) u=dp[u][i]; if(u==v) return u; for(int i=log-1;i>=0;i--) if(dp[v][i]!=dp[u][i]) v=dp[v][i],u=dp[u][i]; return dp[u][0];}void init(int n){ for(int i=0;i<=n;i++) { dp[i][0]=0; head[i]=NULL; deg[i]=0; } cur=g;}int main(){ int t; scanf("%d",&t); while(t--) { int n,u,v; scanf("%d",&n); init(n); for(int i=0;i<n-1;i++) { scanf("%d%d",&u,&v); addnode(u,v); deg[v]++; dp[v][0]=u; } for(int i=1;i<=n;i++) if(deg[i]==0){dfs(i);break;} scanf("%d%d",&u,&v); printf("%d\n",lca(u,v)); }}HDU 2586
Lca#define N 50005vector<int> mp[N],w[N],query[N],num[N];int p[N],d[N],res[N];bool vis[N];int n;void Init(){ int i; for(i=1;i<=n;i++) { mp[i].clear(); w[i].clear(); query[i].clear(); num[i].clear(); p[i]=i; d[i]=0; vis[i]=false; }}int Find(int x){ if(p[x]!=x) p[x]=Find(p[x]); return p[x];}void Union(int x,int y){ x=Find(x); y=Find(y); if(x!=y) p[y]=x;}void Tarjan(int cur,int v){ int size,i,tmp; vis[cur]=true; d[cur]=v; size=mp[cur].size(); for(i=0;i<size;i++) { tmp=mp[cur][i]; if(vis[tmp]) continue; Tarjan(tmp,v+w[cur][i]); Union(cur,tmp); } size=query[cur].size(); for(i=0;i<size;i++) { tmp=query[cur][i]; if(!vis[tmp])continue; res[num[cur][i]]=d[cur]+d[tmp]-2*d[Find(tmp)]; }}int main(){ int T,q,a,b,c,i; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&q); Init(); for(i=1;i<n;i++) { scanf("%d%d%d",&a,&b,&c); mp[a].push_back(b); w[a].push_back(c); mp[b].push_back(a); w[b].push_back(c); } for(i=0;i<q;i++) { scanf("%d%d",&a,&b); query[a].push_back(b); query[b].push_back(a); num[a].push_back(i); num[b].push_back(i); } Tarjan(1,0); for(i=0;i<q;i++) printf("%d\n",res[i]); } return 0;}
0 0
- LCA最近公共祖先(RMQ、Tarjan)
- 最近公共祖先LCA模板(Tarjan/RMQ)
- 最近公共祖先(LCA) RMQ解决
- [算法] LCA 最近公共祖先 (Tarjan)
- 最近公共祖先LCA tarjan
- 最近公共祖先(LCA)算法实现过程 【Tarjan离线+倍增在线+RMQ】
- 最近公共祖先(LCA)和RMQ问题
- LCA问题(最近公共祖先问题)+ RMQ问题
- 【转载】最近公共祖先LCA:RMQ转化
- 最近公共祖先LCA:RMQ转化
- Tarjan算法求LCA(最近公共祖先)
- Tarjan离线算法求最近公共祖先(LCA)
- Tarjan离线算法求最近公共祖先(LCA)
- LCA(最近公共祖先)tarjan算法学习笔记
- 最近公共祖先LCA:Tarjan算法(介绍1)
- 最近公共祖先LCA:Tarjan算法(介绍2)
- Tarjan离线算法求最近公共祖先(LCA)
- [图论] LCA(最近公共祖先)Tarjan 离线算法
- 根据某字段的不同属性值对另一字段的值进行合并
- noi 1999 生日蛋糕
- leetcode题解日练--2016.7.11
- uboot内核参数的传递与内核解析uboot传递的内核参数
- 网络工具类WebHttpUtils
- LCA最近公共祖先(RMQ、Tarjan)
- 提高项目30.4-统计字符串的长度
- 【Python学习笔记】模块
- cpp环境【VIJOS1698】导游
- Reverse Bits
- TextView不能右对齐?!
- python学习(3)- 深入流程控制
- Android : Drawable之getIntrinsicWidth()和getIntrinsicHeight()
- 观察者模式