Codeforces-Gadget Hackwrench-LCA最近公共祖先
来源:互联网 发布:淘宝潮男鞋店铺推荐 编辑:程序博客网 时间:2024/05/01 01:17
题目链接:http://codeforces.com/gym/100685/problem/G
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.
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).
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.
41 23 14 161 23 22 34 24 32 1
YesYesNoYesNoNo
一道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 100010using 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"); } }}
- Codeforces-Gadget Hackwrench-LCA最近公共祖先
- 最近公共祖先LCA
- 最近公共祖先(LCA)
- Lca 最近公共祖先
- LCA----最近公共祖先
- LCA (最近公共祖先)
- LCA最近公共祖先
- LCA 最近公共祖先
- 最近公共祖先 LCA
- LCA--最近公共祖先
- LCA(最近公共祖先)
- LCA最近公共祖先
- LCA(最近公共祖先)
- LCA 最近公共祖先
- 最近公共祖先LCA
- LCA 最近公共祖先
- 【LCA】最近公共祖先
- LCA最近公共祖先
- SIMD(MMX/SSE/AVX)变量命名规范心得
- ACE日志系统
- iOS 怎样通过UDP发送广播寻找设备,拿到ip地址,然后用TCP 连接设备
- 在aix环境中用java实现自动发邮件告警
- C++之tinyXML的使用详解
- Codeforces-Gadget Hackwrench-LCA最近公共祖先
- TiXmlHandle的使用-简化tinyxml的代码
- tinyxml源码解析(中)
- tinyxml源码解析(上)
- ADT的配置环境
- STL使用总结
- STL之二:vector容器用法详解
- STL学习系列之一——标准模板库STL介绍
- STL之一:字符串用法详解