Gym 100685 G Gadget Hackwrench LCA+DFS标记
来源:互联网 发布:js根据name获取标签 编辑:程序博客网 时间:2024/05/17 23:49
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
题目链接:http://codeforces.com/gym/100685/problem/G
题目大意:给定一张有向无环图,n个点,问从一点A到另外一点B是否存在一条通路可达。
思路:首先,以双向边的形式构建出LCA的st表,并标记正向边(flag = 0)与反向边(flag = 1)。然后,DFS一次,记录三项内容,分别是该节点所在深度cnt[],从该点沿正向走的最远距离dir_u[]和从该点沿反向走的最远距离dir_v[],于是,对于一组查询A和B,从A到B可达,当且仅当A到lca的距离不超过A的正向最远距离,同时B到lca的距离不超过B的反向最远距离。
AC代码:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <algorithm>#include <vector>#include <limits.h>#include <queue>#include <map>#include <set>using namespace std;typedef long long LL;#define pll pair<LL, LL>#define pii pair<int, int>#define X first#define Y second#define MAXN 200010#define lson l, mid, (rt << 1)#define rson mid + 1, r, (rt << 1 | 1)const double eps = 1e-10;int head[MAXN];int dp[MAXN][20], deep[MAXN];int dir_u[MAXN], dir_v[MAXN], cnt[MAXN];int totedge = 0, t, n, Q;bool vis[MAXN];struct node { int to, next, flag;} edge[MAXN << 1];void init() { totedge = 0; memset(vis, false, sizeof vis); memset(head, -1, sizeof head); memset(dp, 0, sizeof dp); memset(deep, 0, sizeof deep); memset(dir_u, 0, sizeof dir_u); memset(dir_v, 0, sizeof dir_v); memset(cnt, 0, sizeof cnt);}void add(int from, int to, int flag) { edge[totedge].to = to; edge[totedge].next = head[from]; edge[totedge].flag = flag; head[from] = totedge++;}void DFS(int u, int step) { if(vis[u]) return ; vis[u] = true; if(step == 0) dp[u][0] = u; deep[u] = step; for(int i = 1; i < 20; i++) dp[u][i] = dp[dp[u][i-1]][i-1]; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(vis[v]) continue; dp[v][0] = u; DFS(v, step + 1); }}int LCA(int u, int v) { if(deep[u] > deep[v]) swap(u, v); int deep_len = deep[v] - deep[u]; int tu = u, tv = v; for(int j = deep_len, i = 0; j ; j>>=1, i++) { if(j & 1) tv = dp[tv][i]; } if(tu == tv) return tu; for(int i = 20 - 1; i >= 0; i--) { if(dp[tu][i] == dp[tv][i]) continue; tu = dp[tu][i], tv = dp[tv][i]; } return dp[tu][0];}void DFS2(int u, int pre) { for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v == pre) continue; cnt[v] = cnt[u] + 1; if(edge[i].flag == 0) { dir_v[v] = dir_v[u] + 1; dir_u[v] = 0; } else { dir_u[v] = dir_u[u] + 1; dir_v[v] = 0; } DFS2(v, u); }}int main() { while(~scanf("%d", &n)) { init(); int a, b; for(int i = 0; i < n - 1; i++) { scanf("%d%d", &a, &b); add(a, b, 0); add(b, a, 1); } DFS(1, 0); scanf("%d", &Q); DFS2(1, -1); while(Q--) { scanf("%d%d", &a, &b); int lca = LCA(a, b); int cnt1 = cnt[a] - cnt[lca]; int cnt2 = cnt[b] - cnt[lca]; if(cnt1 > dir_u[a] || cnt2 > dir_v[b]) { puts("No"); } else puts("Yes"); } } return 0;}
- Gym 100685 G Gadget Hackwrench LCA+DFS标记
- Gym 100685G Gadget Hackwrench (LCA)
- Gym 100685G Gadget Hackwrench(LCA)
- Gym 100685G Gadget Hackwrench (LCA)
- Codeforces/gym/100685/problem/G Gadget Hackwrench ( LCA )
- Codeforces-Gadget Hackwrench-LCA最近公共祖先
- Gym100685GGadget Hackwrench(LCA)
- Gym 100712G Heavy Coins(DFS)
- Gym 100685G
- Gym 101142G Gangsters in Central City【思维+Lca】
- Gym 100512D Dynamic LCA ((LCA 在线算法DFS+ST) + 分类讨论!!)
- GYM 100685 G【并查集】
- Codeforces Gym 101201G Maximum Islands (dfs求联通块+最大独立集)
- codeforces gym 100548G
- Gym 100269G-Garage
- CodeForces Gym 100735G
- CodeForces Gym 100735G
- Gym 100971G Repair
- MMD_4b_SVD
- HDOJ 5498 Tree
- 线性筛
- main函数
- iOS 常用控件
- Gym 100685 G Gadget Hackwrench LCA+DFS标记
- 欢迎使用CSDN-markdown编辑器
- 自己的练习二之构造函数与初始化列表
- A018-布局之TableLayout
- 自己的练习三之复制构造函数
- IOS面试题汇总
- AOP运行过程解析
- ASP.NET MVC + Bootstrap + XML + WCF 封装短信验证服务(一)
- 动态变量和静态变量的区别