(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 ...
随机推荐
- java新项目的eclipse统一配置记录
1.new java file的模版 /** * @Title:${file_name} * @Copyright: Copyright (c) 2016 * @Description: * < ...
- NHibernate系列文章十八:NHibernate关系之一对多(附程序下载)
摘要 这篇文章介绍NHibernate最实用的内容:关系映射. NHibernate的关系映射方式有三种: Set:无序对象集合,集合中每一个元素不能重复. List:有序对象集合,集合中的元素可以重 ...
- SQL笔记-第七章,表连接
SQL中使用JOIN 关键字来使用表连接.表连接有多种不同的类型,被主流数据库系统支持的有交叉连接(CROSS JOIN).内连接(INNER JOIN).外连接(OUTTER JOIN),另外在有的 ...
- MyBatis复习
一.对JDBC的总结 1.数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能. 解决方案:使用数据库连接池管理数据库连接. 2.将sql语句硬 ...
- C# 远程网络唤醒介绍及代码
一.定义 网络唤醒:唤醒休眠状态下的计算机,而不是已关机的计算机. 优势:可通过定时功能实现自动唤醒计算机,减少人力使用. 实现方法:通过被唤醒机的MAC地址进行广播发送请求,唤醒计算机. 二.硬件设 ...
- CString转换成char*
CString转换成char* :charSource = (char*)strSource.GetBuffer(0); 法2:charSource = (char*)strSource.GetBuf ...
- 循序渐进之Spring AOP(5) - 创建切面
在掌握了可用的增强后,接下来要做的就是精确的描述切点.前面的示例都是指定一个目标类并把增强织入到所有方法中,实际开发显然会有更精细的筛选需求,比如对所有类中名称以test结尾的方法加入监控执行时间,或 ...
- JSTL和EL的区别
JSTL(JSP Standard Tag Library,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的.JSTL只能运行在支持JSP1.2 ...
- 当前JS文件中加入其他js文件
注意:在html文件导入a.js时,应该把script></script写在/body>后面,否则 document.write()方法有问题. 在载入页面后,浏览器输出流自动关闭: ...
- Repeater展示表格
1.可以不用table展示数据 <asp:Repeater ID="Repeater1" runat="server"> <ItemTempl ...