Codeforces-Gadget Hackwrench-LCA最近公共祖先
2016-03-08 16:48
453 查看
题目链接:http://codeforces.com/gym/100685/problem/G
Gadget Hackwrench
time limit per test
2 seconds
memory limit per test
64 megabytes
input
standard input
output
standard output
Chip 'n' Dale rescue rangers! But observant viewers know that help is usually required by Chip and Dale themselves. Today you are in the role of cunning Gadget Hackwrench.
So, Chip and Dale are again in the paws of Fat Cat. He doesn't like rodents much and therefore prepared a treacherous test. He is going to put them to a labyrinth and see if they can escape from it. The labyrinth is actually built as a tree where each edge
has fixed direction (by definition tree is a connected unoriented graph without cycles).
Gadget has intercepted a talk between Fat Cat and his henchmen about future tests. For each test round she knows the exact location where Chip and Dale are to be put by Fat Cat and the location of an exit. Gadget wants to compute whether they will be able to
find an exit for each test.
Input
The first line of input contains an integer N (1 ≤ N ≤ 105) —
the number of vertices in a graph.
On the next N - 1 lines of input directed arcs of the tree are given. On the (i + 1)th line
integer numbers ai and bi are
given (1 ≤ ai, bi ≤ N)
denoting an arc from vertex ai to
vertex bi.
It is guaranteed that arcs a1, a2, ..., an - 1 without
orientation form a tree.
Then a string with integer number M (1 ≤ M ≤ 105)
is given — the number of queries to process. Next M lines describe queries:(n + 1 + i)th line
contain integers xi and yi (1 ≤ xi, yi ≤ N).
Output
For each query please output a separate line containing 'Yes' (without quotes) if graph contains a path between xi and yi,
or 'No' (without quotes) in other case.
Examples
input
output
一道LCA的题,记录每个节点到根节点需要经过几个方向向下的边(用flag数组来存)。然后最后判断是否合法只需要判断,这两个点到他们的最近公共祖先是否合法。比如LCA(a,b)为a,b的最近公共祖先,这两个点分别为a,b;那么就是判断flag[a]-flag[LCA(a,b)]是否等于0以及flag[b]-flag[LCA(A,B)]是否等于他们的深度差。LCA(a,b)为a,b的最近公共祖先。
代码如下。
Gadget Hackwrench
time limit per test
2 seconds
memory limit per test
64 megabytes
input
standard input
output
standard output
Chip 'n' Dale rescue rangers! But observant viewers know that help is usually required by Chip and Dale themselves. Today you are in the role of cunning Gadget Hackwrench.
So, Chip and Dale are again in the paws of Fat Cat. He doesn't like rodents much and therefore prepared a treacherous test. He is going to put them to a labyrinth and see if they can escape from it. The labyrinth is actually built as a tree where each edge
has fixed direction (by definition tree is a connected unoriented graph without cycles).
Gadget has intercepted a talk between Fat Cat and his henchmen about future tests. For each test round she knows the exact location where Chip and Dale are to be put by Fat Cat and the location of an exit. Gadget wants to compute whether they will be able to
find an exit for each test.
Input
The first line of input contains an integer N (1 ≤ N ≤ 105) —
the number of vertices in a graph.
On the next N - 1 lines of input directed arcs of the tree are given. On the (i + 1)th line
integer numbers ai and bi are
given (1 ≤ ai, bi ≤ N)
denoting an arc from vertex ai to
vertex bi.
It is guaranteed that arcs a1, a2, ..., an - 1 without
orientation form a tree.
Then a string with integer number M (1 ≤ M ≤ 105)
is given — the number of queries to process. Next M lines describe queries:(n + 1 + i)th line
contain integers xi and yi (1 ≤ xi, yi ≤ N).
Output
For each query please output a separate line containing 'Yes' (without quotes) if graph contains a path between xi and yi,
or 'No' (without quotes) in other case.
Examples
input
4 1 2 3 1 4 1 6 1 2 3 2 2 3 4 2 4 3 2 1
output
Yes Yes No Yes No No
一道LCA的题,记录每个节点到根节点需要经过几个方向向下的边(用flag数组来存)。然后最后判断是否合法只需要判断,这两个点到他们的最近公共祖先是否合法。比如LCA(a,b)为a,b的最近公共祖先,这两个点分别为a,b;那么就是判断flag[a]-flag[LCA(a,b)]是否等于0以及flag[b]-flag[LCA(A,B)]是否等于他们的深度差。LCA(a,b)为a,b的最近公共祖先。
代码如下。
//RMQst表来做LCA //树的节点是从1到n开始排列。 //fat[i][j]表示第i个节点的第2^j个祖先是谁 //2^20 = 1 048 576 #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> #define maxn 100010 using namespace std; int flag[maxn]; int fat[maxn][30]; int len[maxn]; int n; struct node{ int val,dir; }; vector<node>v[maxn]; void dfs(int now,int father) { fat[now][0]=father; len[now]=len[father]+1; for(int i=0;i<v[now].size();i++) { if(v[now][i].val==father) continue; if(v[now][i].dir) flag[v[now][i].val]=flag[now]+1; else flag[v[now][i].val]=flag[now]; dfs(v[now][i].val,now); } } void init() { memset(len,0,sizeof(len)); memset(fat,0,sizeof(fat)); memset(flag,0,sizeof(flag)); int i,j; dfs(1,0); for(int i=1;i<=19;i++) { for(int j=1;j<=n;j++) { fat[j][i]=fat[fat[j][i-1]][i-1]; } } } int lca(int x,int y) { if(len[x]>len[y]) swap(x,y); //保证x的深度较小 //下面只需要将y拉到x的位置就好 for(int i=19;i>=0;i--) { if(len[fat[y][i]]>=len[x]) y=fat[y][i]; } //现在x,y已经在同一高度 //可以求LCA了 if(x==y) { return x;//这是x和y其中一个是另一个的祖宗 } for(int i=19;i>=0;i--) { if(fat[y][i]!=fat[x][i]) { y=fat[y][i]; x=fat[x][i]; } } return fat[x][0]; } int main() { int uu,vv; int m; while(scanf("%d",&n)!=EOF) { for(int i=0;i<maxn;i++) { v[i].clear(); } for(int i=1;i<n;i++) { scanf("%d%d",&uu,&vv); node vvv,uuu; vvv.val=vv; uuu.val=uu; uuu.dir=1; vvv.dir=0; v[uu].push_back(vvv); v[vv].push_back(uuu); } init(); scanf("%d",&m); for(int i=1;i<=m;i++) { flag[0]=0; scanf("%d%d",&uu,&vv); int root=lca(uu,vv); int fuck,cao; fuck=flag[uu]-flag[root]; cao=flag[vv]-flag[root]; if(cao==0&&fuck==len[uu]-len[root]) flag[0]=1; if(flag[0]) printf("Yes\n"); else printf("No\n"); } } }
相关文章推荐
- 在aix环境中用java实现自动发邮件告警
- JSON详解
- APP测试功能点总结
- iOS中的单例设计模式详解
- 怎样用jquery添加HTML代码
- Error:identifer “blockIdx” and __syncthreads() undefined
- routeros在ESX环境ping不通网关的问题
- preg_split
- Cube process 或者 deploy 时发生数据库因权限问题无法连接的解决办法
- 文章标题
- 得到不知道维度的string数组的维度
- java的动态代理机制
- C#-界面假死
- 深度剖析Android MVPR架构模式(一)
- iOS测试证书创建,真机测试
- android背景选择器selector用法汇总
- 【慕课笔记】4-5 字节缓冲流
- 事务
- 135.Which three statements are true regarding subqueries? (Choose three.)
- Python -- 基本应用