(Gym 100685G) Gadget Hackwrench(LCA在线ST)
2 seconds
64 megabytes
standard input
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 definitiontree 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)thline 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.
4 1 2 3 1 4 1 6 1 2 3 2 2 3 4 2 4 3 2 1
Yes Yes No Yes No No 由于3 2能够通行而2 3无法通行可知通行有方向上的限制,为了解决这种问题,可以人为地在每一对(u,v)之间加上一个负边,长度为-1,而设原来方向的边为+1,
那么对于每个lca来说,如果u到lca的距离由wei负边构成,v到lca的距离由正边构成,那么这两个点联通
#include <iostream>
#include <cstdio>
#include <cstring>
#define scan(x) scanf("%d",&x)
#define scan2(x,y) scanf("%d%d",&x,&y)
#define scan3(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
const int Max=1e5+;
const int E=2e5+;
int head[Max],nex[E],pnt[E],cost[E],edge;
int vex[Max<<],R[Max<<],vis[Max],dis[Max],first[Max],tot;
int n;
void Addedge(int u,int v,int c)
{
pnt[edge]=v;
cost[edge]=c;
nex[edge]=head[u];
head[u]=edge++;
}
void dfs(int u,int deep)
{
vis[u]=;
vex[++tot]=u;
first[u]=tot;
R[tot]=deep;
for(int x=head[u]; x!=-; x=nex[x])
{
int v=pnt[x],c=cost[x];
if(!vis[v])
{
dis[v]=dis[u]+c;
dfs(v,deep+);
vex[++tot]=u;
R[tot]=deep;
}
}
}
int dp[Max<<][];
void ST(int n)
{
int x,y;
for(int i=; i<=n; i++) dp[i][]=i;
for(int j=; (<<j)<=n; j++)
{
for(int i=; i+(<<j)-<=n; i++)
{
x=dp[i][j-];
y=dp[i+(<<(j-))][j-];
dp[i][j]=(R[x]<R[y]?x:y);
}
}
}
int RMQ(int l,int r)
{
int k=,x,y;
while((<<(k+))<=r-l+) k++;
x=dp[l][k];
y=dp[r-(<<k)+][k];
return (R[x]<R[y])?x:y;
}
int LCA(int u,int v)
{
int x=first[u],y=first[v];
if(x>y) swap(x,y);
int res=RMQ(x,y);
return vex[res];
}
int vis2[Max];
void Init()
{
edge=;
memset(head,-,sizeof(head));
memset(nex,-,sizeof(nex));
memset(vis,,sizeof(vis));
memset(vis2,,sizeof(vis2));
}
int main()
{
int T,Q;
Init();
int u,v,c;
scan(n);
for(int i=; i<n-; i++)
{
scan2(u,v);
Addedge(u,v,);
Addedge(v,u,-);
vis2[v]=;
}
int root=;
for(int i=; i<=n; i++) if(!vis2[i])
{
root=i;
break;
}
tot=;
dis[root]=;
dfs(root,);
ST(*n);
scan(Q);
while(Q--)
{
scan2(u,v);
int lca=LCA(u,v);
cout<<lca<<endl;
int depu=R[first[u]]-R[first[lca]];
int depv=R[first[v]]-R[first[lca]];
int disu=dis[u]-dis[lca];
int disv=dis[v]-dis[lca];
//lca与u之间都要为负边,lca与v之间都要为正边
//u到lca距离全负,因为u的父亲由负边而来
//v到lca距离全正
if(depu==-disu&&depv==disv) puts("Yes");
else puts("No");
}
return ;
}
(Gym 100685G) Gadget Hackwrench(LCA在线ST)的更多相关文章
- hdu 2586(LCA在线ST)
How far away ? Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission(s): A ...
- LCA Codeforces 100685G Gadget Hackwrench
题目传送门 题意:一棵有向的树,问u到v是否可达 分析:假设是无向树,DFS时正向的权值+1,反向的权值-1,然后找到LCA后判断dep数组和d数组就可以了 /******************** ...
- HDU 2586 How far away ?(经典)(RMQ + 在线ST+ Tarjan离线) 【LCA】
<题目链接> 题目大意:给你一棵带有边权的树,然后进行q次查询,每次查询输出指定两个节点之间的距离. 解题分析:本题有多重解决方法,首先,可用最短路轻易求解.若只用LCA解决本题,也有三种 ...
- LCA在线算法ST算法
求LCA(近期公共祖先)的算法有好多,按在线和离线分为在线算法和离线算法. 离线算法有基于搜索的Tarjan算法较优,而在线算法则是基于dp的ST算法较优. 首先说一下ST算法. 这个算法是基于RMQ ...
- POJ 1470 Closest Common Ancestors (LCA, dfs+ST在线算法)
Closest Common Ancestors Time Limit: 2000MS Memory Limit: 10000K Total Submissions: 13370 Accept ...
- 求LCA最近公共祖先的在线ST算法_C++
ST算法是求最近公共祖先的一种 在线 算法,基于RMQ算法,本代码用双链树存树 预处理的时间复杂度是 O(nlog2n) 查询时间是 O(1) 的 另附上离线算法 Tarjan 的链接: http ...
- Gym100685G Gadget Hackwrench(倍增LCA)
题目大概说一棵边有方向的树,q个询问,每次询问结点u是否能走到v. 倍增LCA搞即可: 除了par[k][u]表示u结点往上走2k步到达的结点, 再加上upp[k][u]表示u结点往上走2k步经过边的 ...
- LCA在线算法详解
LCA(最近公共祖先)的求法有多种,这里先介绍第一种:在线算法. 声明一下:下面的内容参考了http://www.cnblogs.com/scau20110726/archive/2013/05/26 ...
- poj 1330 Nearest Common Ancestors lca 在线rmq
Nearest Common Ancestors Description A rooted tree is a well-known data structure in computer scienc ...
随机推荐
- Android开发--布局二
1.Andrid:控件布局(表格布局)TableLayout 有多少个TableRow对象就有多少行, 列数等于最多子控件的TableRow的列数 直接在TableLayout加控件,控件会占据一行 ...
- Office2007在安装、卸载过程中出错的解决办法
Micorsoft office professional plus 2007在安装过程中出错,错误1706 如果在安装OFFICE 2007的 时候,遇到“Microsoft Office 2007 ...
- 开源文档管理工具Joomla的网站安装
1.配置PHP开发环境(Apache.PHP.MySQL) 2.安装Joomla网站: 1. 下载安装包 http://www.joomla.org/download.html 2. 登陆Jo ...
- zabbix3.0.4监控mysql主从同步
zabbix3.0.4监控mysql主从同步 1.监控mysql主从同步原理: 执行一个命令 mysql -u zabbix -pzabbix -e 'show slave status\G' 我们在 ...
- VC++ 动态生成 成组的 RadioButton 按钮组
先说一下 静态创建的方法: 单选按钮也属于CButton类,但由于单选按钮总是成组使用的,所以它在制作和使用上与普通按钮有一定区别.假设有三个单选按钮组成一组,初始时,第一个单选按钮处于选中状态.我们 ...
- GBDT(MART) 迭代决策树入门教程 | 简介
GBDT(MART) 迭代决策树入门教程 | 简介 http://blog.csdn.net/w28971023/article/details/8240756
- lucene query
在lucene的搜索中,最重要的无疑就是对query的理解和掌握了.这里扒拉一下源码(版本3.5.0)的query和query实现: query是一个抽象类,实现类有以下几个: termQuery m ...
- Python验证码识别处理实例(转载)
版权声明:本文为博主林炳文Evankaka原创文章,转载请注明出处http://blog.csdn.net/evankaka 一.准备工作与代码实例 1.PIL.pytesser.tesseract ...
- java利用jxl操作Excel
/** * 把从数据库查询到的数据,写入电子表格 * * @throws Exception */ public void createXls() throws Exception { Dao dao ...
- C#的UDP服务器
最新优化版本 /* http://www.cnblogs.com/zengqinglei/archive/2013/04/27/3046119.html */ using System; using ...