Description
给定一个n个顶点的有向图,每个顶点有且仅有一条出边。
对于顶点i,记它的出边为(i, a[i])。
再给出q组询问,每组询问由两个顶点a、b组成,要求输出满足下面条件的x、y:
1. 从顶点a沿着出边走x步和从顶点b沿着出边走y步后到达的顶点相同。
2. 在满足条件1的情况下max(x,y)最小。
3. 在满足条件1和2的情况下min(x,y)最小。
4. 在满足条件1、2和3的情况下x>=y。
如果不存在满足条件1的x、y,输出-1 -1。
Input
第一行两个正整数n和q (n,q<=500,000)。
第二行n个正整数a[1],a[2],...,a[n] (a[i]<=n)。
下面q行,每行两个正整数a,b (a,b<=n),表示一组询问。
Output
输出q行,每行两个整数。

思路:其实我觉得基环树题就是暴力模拟题……先找环,然后有多种情况,在环上某点的同一子树下,在环上不同子树下,不在同一联通块内,一一处理即可

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + ; int head[N], now;
struct edges{
int to, next, w;
}edge[N<<];
void add(int u, int v, int w){ edge[++now] = {v, head[u], w}; head[u] = now;}
void read(int &x){
int f=;x=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
x*=f;
} int n, q, dfn[N], sz, pre[N], tot, c[N], dict[N], bel[N], fa[N][], dep[N], pos[N];
vector<int> cir[N];
void fcur(int x){
dfn[x] = ++sz; bel[x] = tot;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(v == pre[x]) continue;
if(dfn[v]){
if(dfn[v] < dfn[x]) continue;
cir[tot].push_back(x); c[x] = tot;
for(; x != v; v = pre[v]){
cir[tot].push_back(v), c[v] = tot;
}
}else pre[v] = x, fcur(v);
}
return ;
} void dfs(int x, int father, int root){
dict[x] = root; fa[x][] = father;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(v == father || c[v]) continue;
dep[v] = dep[x] + ;
dfs(v, x, root);
}
}
int LCA(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
int k=dep[u]-dep[v];
for(int i=;i<=;i++)
if((<<i)&k) u=fa[u][i];
if(u==v) return u;
for(int i=;i>=;i--)
if(fa[u][i]!=fa[v][i])
u=fa[u][i],v=fa[v][i];
return fa[u][];
}
void dfs2(int x, int step){
pos[x] = step;
for(int i = head[x]; i; i = edge[i].next){
int v = edge[i].to;
if(edge[i].w && !pos[v]) dfs2(v, step + );
}
}
int main(){
read(n), read(q);
int x, y;
for(int i = ; i <= n; i++){
read(x);
add(i, x, ), add(x, i, );
}
for(int i = ; i <= n; i++){
if(!dfn[i]){
sz = ; tot++;
fcur(i);
}
}
for(int i = ; i <= tot; i++){
dfs2(cir[i][], );
for(int j = ; j < cir[i].size(); j++){
x = cir[i][j];
dict[x] = x;
dfs(x, x, x);
}
}
for(int j = ; j <= ; j++)
for(int i = ; i <= n; i++)
fa[i][j + ] = fa[fa[i][j]][j];
while(q--){
scanf("%d%d", &x, &y);
if(bel[x] != bel[y]){
puts("-1 -1"); continue;
}else if(dict[x] == dict[y]){
int lca = LCA(x, y);
printf("%d %d\n", dep[x] - dep[lca], dep[y] - dep[lca]);
}else{
int rt1 = dict[x], rt2 = dict[y], siz = cir[bel[x]].size();
int s1 = dep[x] - dep[rt1], s2 = dep[y] - dep[rt2];
int k1, k2;
if(pos[rt1] < pos[rt2]) k1 = pos[rt2] - pos[rt1], k2 = siz - k1;
else k2 = pos[rt1] - pos[rt2], k1 = siz - k2;
int tmp1 = s1 + k1, tmp2 = s2 + k2;
if(max(tmp1, s2) != max(s1, tmp2)){
if(max(tmp1, s2) > max(s1, tmp2)) printf("%d %d\n", s1, tmp2);
else printf("%d %d\n", tmp1, s2);
continue;
}
else if(min(tmp1, s2) != min(s1, tmp2)){
if(min(tmp1, s2) > min(s1, tmp2)) printf("%d %d\n", s1, tmp2);
else printf("%d %d\n", tmp1, s2);
continue;
}
else{
if(tmp1 >= s2) printf("%d %d\n", tmp1, s2);
else printf("%d %d\n", s1, tmp2);
}
}
}
return ;
}

BZOJ2791 Rendezvous的更多相关文章

  1. 【BZOJ2791】[Poi2012]Rendezvous 倍增

    [BZOJ2791][Poi2012]Rendezvous Description 给定一个n个顶点的有向图,每个顶点有且仅有一条出边.对于顶点i,记它的出边为(i, a[i]).再给出q组询问,每组 ...

  2. [BZOJ2791][Poi2012]Rendezvous

    2791: [Poi2012]Rendezvous Time Limit: 25 Sec  Memory Limit: 128 MBSubmit: 95  Solved: 71[Submit][Sta ...

  3. [BZOJ2791]:[Poi2012]Rendezvous(塔尖+倍增LCA)

    题目传送门 题目描述 给定一个有n个顶点的有向图,每个顶点有且仅有一条出边.每次询问给出两个顶点${a}_{i}$和${b}_{i}$​​,求满足以下条件的${x}_{i}$和${y}_{i}$:   ...

  4. TensorFlow中的通信机制——Rendezvous(二)gRPC传输

    背景 [作者:DeepLearningStack,阿里巴巴算法工程师,开源TensorFlow Contributor] 本篇是TensorFlow通信机制系列的第二篇文章,主要梳理使用gRPC网络传 ...

  5. TensorFlow中的通信机制——Rendezvous(一)本地传输

    背景 [作者:DeepLearningStack,阿里巴巴算法工程师,开源TensorFlow Contributor] 在TensorFlow源码中我们经常能看到一个奇怪的词——Rendezvous ...

  6. Loadrunner集合点Rendezvous知识

    摘自: http://blog.csdn.net/richnaly/article/details/7967364 集合点的意思时等到特定的用户数后再一起执行某个操作,比如一起保存,一起提交(我们通常 ...

  7. 【BZOJ 2791】 2791: [Poi2012]Rendezvous (环套树、树链剖分LCA)

    2791: [Poi2012]Rendezvous Description 给定一个n个顶点的有向图,每个顶点有且仅有一条出边.对于顶点i,记它的出边为(i, a[i]).再给出q组询问,每组询问由两 ...

  8. 「POI2012」约会 Rendezvous

    #2691. 「POI2012」约会 Rendezvous 这题我简直不想说什么了,什么素质,卡常数…… “每个顶点有且仅有一条出边”,所以是一道基环树的题,首先tarjan缩点,在缩完点后的图上求a ...

  9. 约会Rendezvous

    约会 Rendezvous 内存限制:128 MiB 时间限制:1000 ms 标准输入输出     题目描述 给定一个有 nnn 个顶点的有向图,每个顶点有且仅有一条出边.每次询问给出两个顶点 ai ...

随机推荐

  1. Selenium自动化测试第一天(上)

    如有任何学习问题,可以添加作者微信:lockingfree 目录 Selenium自动化测试基础 Selenium自动化测试第一天(上) Selenium自动化测试第一天(下) Selenium自动化 ...

  2. Java开发工程师(Web方向) - 03.数据库开发 - 第3章.SQL注入与防范

    第3章--SQL注入与防范 SQL注入与防范 经常遇到的问题:数据安全问题,尤其是sql注入导致的数据库的安全漏洞 国内著名漏洞曝光平台:WooYun.org 数据库泄露的风险:用户信息.交易信息的泄 ...

  3. Response对象及常用方法

    void addCookie(Cookie cookie)给客户端添加一个Cookie对象,以保存客户端的信息 void addDateHeader(String name,long value) 添 ...

  4. 记一次Log4j2日志无法输出的 心酸史

    问题描述:部分日志无法输出到日志文件中. 项目中的代码: @Resource private ConfigInfo configInfo; private static final Logger lo ...

  5. Android开发-API指南-<receiver>

    <receiver> 英文原文:http://developer.android.com/guide/topics/manifest/receiver-element.html 采集(更新 ...

  6. Android开发-API指南-<permission>

    <permission> 英文原文:http://developer.android.com/guide/topics/manifest/permission-element.html 采 ...

  7. 技能get,React的优雅升级!

    今日,我们不啖鸡汤,不饮鸡血 只有干货——关于React的优雅升级 双手奉上,来,干了! -2019年第4期- 夫 子 说 本次升级基础包情况:react 15.6 -> 16.6 升级流程: ...

  8. Paper Reading - CNN+CNN: Convolutional Decoders for Image Captioning

    Link of the Paper: https://arxiv.org/abs/1805.09019 Innovations: The authors propose a CNN + CNN fra ...

  9. mac os x下应用endnote异常解决办法

    最近在用Office+Endnote写论文,使用拼音输入法换字时会出现重字和拼音的情况,比如我想打“桥连”,最终出现的是"qiao'lian桥lian桥连”.后来发现这个问题时由endnot ...

  10. nordic mesh 任务调度实现

    nordic mesh 任务调度实现 nordic mesh的任务调度室基于定时器实现的,有两个链表结构维护任务. 需要注意的是,任务调度的部分接口只能在"bearer event" ...