SDNU 1492.Problem_A LCA倍增算法
来源:互联网 发布:代驾软件 编辑:程序博客网 时间:2024/06/08 19:02
1492.Problem_A
Time Limit: 1000 MS Memory Limit: 32768 KB
SDNU ACM-ICPC Association is in a mess. If you join it, you should be in the shadow of a person. This person, we call him "dalao". For example, there are two rookies, C and D, rely on A. We can say that A is the closest dalao of rookies C and D.For another example, A have two heelers C and D, D have two heelers E and F.We can know that A is the closest dalao of E and C.
But with the growth of Association, we cannot find the closest dalao between two rookies. So we need your help.
There will be a series of examples.
For each input, the first line contains two integers N. N means the number of people.
Followed by the N-1 lines, each line contains two integers A and B. It means that A is a dalao of B.
Then the next line, contains two integers A and B. It means that we want to know who is the closest dalao between A and B.
Output
For each input, you should output the name of the closest dalao.If you cannot find this dalao, you should output "I am so bad."
7
1 2
1 3
2 5
2 6
6 7
6 8
3 5
Sample Output
1
Hint
Remember that a rookie is also a dalao of itself
For example:
Input
3
1 2
2 3
2 3
Output
2
选拔赛的一道题目,题意很好理解,简单说就是LCA(最近公共祖先),不过之前没怎么做过这类题目,所以也一直没有整理过自己的模板.....翻到一个dfs+ST的算法就直接敲了,然后....TLE了,才看到后面有更快的算法,不过离比赛结束还剩10分钟已经没时间了,所以就这样放弃了。结果比赛结束下来,敲的后面的倍增算法就A了.....早知道该先敲后面的说,哎呀好气啊。
下面是AC代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int MAXN=10010;const int DEG=20;struct Edge{ int to,next;}edge[MAXN*2];int head[MAXN],tot;void addedge(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++;}void init(){ tot=0; memset(head,-1,sizeof(head));}int fa[MAXN][DEG];int deg[MAXN];void BFS(int root){ queue<int>que; deg[root]=0; fa[root][0]=root; que.push(root); while(!que.empty()) { int tmp=que.front(); que.pop(); for(int i=1;i<DEG;i++) { fa[tmp][i]=fa[fa[tmp][i-1]][i-1]; } for(int i=head[tmp];i!=-1;i=edge[i].next) { int v=edge[i].to; if(v==fa[tmp][0]) continue; deg[v]=deg[tmp]+1; fa[v][0]=tmp; que.push(v); } }}int LCA(int u,int v){ if(deg[u]>deg[v]) swap(u,v); int hu=deg[u],hv=deg[v]; int tu=u,tv=v; for(int det=hv-hu,i=0;det;det>>=1,i++) { if(det&1) tv=fa[tv][i]; } if(tu==tv) return tu; for(int i=DEG-1;i>=0;i--) { if(fa[tu][i]==fa[tv][i]) continue; tu=fa[tu][i]; tv=fa[tv][i]; } return fa[tu][0];}bool flag[MAXN];int main(){ int T; int n; int u,v; while(scanf("%d",&n)!=EOF) { init(); memset(fa,0,sizeof(fa)); memset(deg,0,sizeof(deg)); memset(flag,false,sizeof(flag)); for(int i=1;i<n;i++) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); flag[v]=true; } int root; for(int i=1;i<=n;i++) { if(!flag[i]) { root=i; break; } } BFS(root); scanf("%d%d",&u,&v); if(LCA(u,v)==0) cout<<"I am so bad."<<endl; else cout<<LCA(u,v)<<endl; } return 0;}
1 0
- SDNU 1492.Problem_A LCA倍增算法
- LCA倍增算法(模板)
- lca倍增算法
- lca倍增算法模板
- 倍增算法(LCA)
- LCA的倍增算法
- lca倍增算法
- Algorithm---LCA(倍增算法)
- lca倍增算法学习记录
- 在线倍增算法求LCA
- LCA之倍增算法模板
- LCA算法解析-Tarjan&倍增
- poj1330 lca倍增算法模板
- 图论 LCA在线算法 倍增法
- hdu 4547 CD操作 LCA倍增算法
- hihoCoder1232 Couple Trees LCA倍增算法+二分
- LCA-RMQ倍增算法【codevs.1036
- LCA之倍增及ST算法
- android的智能指针
- 第一章:java概述(java知识点)
- 面向对象的三大属性:封装、继承、多态
- 如何把用laravel5.4写好的网站架构到远程虚拟机上
- ReactNative (API)AsyncStorage存储详解及实例
- SDNU 1492.Problem_A LCA倍增算法
- wordpress不同角色显示不同的菜单栏
- Android—— ListView 的简单用法及定制ListView界面
- PBOC2.0/EMV之TLV格式解析(C++)
- ACM Buy Tickets
- 对韦东山老师移植最新uboot的总结
- Redis实现简单消息队列
- java project单独使用hibernate
- wordpress <4.6.1 语言文件导致的代码执行