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 + 10;int head[N], now;
struct edges{int to, next, w;
}edge[N<<1];
void add(int u, int v, int w){ edge[++now] = {v, head[u], w}; head[u] = now;}
void read(int &x){int f=1;x=0;char s=getchar();while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}x*=f;
}int n, q, dfn[N], sz, pre[N], tot, c[N], dict[N], bel[N], fa[N][22], 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][0] = 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] + 1;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=0;i<=20;i++)if((1<<i)&k) u=fa[u][i];if(u==v) return u;for(int i=20;i>=0;i--)if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];return fa[u][0];
}
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 + 1);}
}
int main(){read(n), read(q);int x, y;for(int i = 1; i <= n; i++){read(x);add(i, x, 1), add(x, i, 0);}for(int i = 1; i <= n; i++){if(!dfn[i]){sz = 0;  tot++;fcur(i);}}for(int i = 1; i <= tot; i++){dfs2(cir[i][0], 1);for(int j = 0; j < cir[i].size(); j++){x = cir[i][j];dict[x] = x;dfs(x, x, x);}}for(int j = 0; j <= 20; j++)for(int i = 1; i <= n; i++)fa[i][j + 1] = 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 0;
}

View Code

转载于:https://www.cnblogs.com/Rorshach/p/8724885.html

BZOJ2791 Rendezvous相关推荐

  1. 【BZOJ2791】[Poi2012]Rendezvous 倍增

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

  2. TIBCO Rendezvous — 技术介绍

      http://blog.csdn.net/tiercel2008/article/details/6799952 TIBCO Rendezvous - 技术介绍 1.1.1.      TIBCO ...

  3. LR中Action,Transaction,Rendezvous,SubmitData的插入顺序请注意

    先说事务,事务(Transaction)    事务(Transaction)是这样一个点,我们为了衡量某个action的性能,需要在action的开始和结束位置插入这样一个范围,这就定义了一个tra ...

  4. 编码器SRT协议三种模式(listener, caller, rendezvous)简介

    本文镜像:https://www.linkpi.cn/archives/1027 本文链接:https://blog.csdn.net/weixin_45326556/article/details/ ...

  5. Python项目:The Ship Rendezvous Problem,利用贪心算法解决船舶交会问题

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 Python利用贪心算法解决船舶交会问题 1 Introduction 2 Python Task Greedy Heuristic ...

  6. [Poi2012]Rendezvous

    题目描述 给定一个n个顶点的有向图,每个顶点有且仅有一条出边. 对于顶点i,记它的出边为(i, a[i]). 再给出q组询问,每组询问由两个顶点a.b组成,要求输出满足下面条件的x.y: 从顶点a沿着 ...

  7. Loadrunner集合点Rendezvous知识

    下面来看看这三种策略的含义: Release when :当所有虚拟用户中的x % 到达集合点进释放,即仅当指定百分比的虚拟用户到达集合点时,才释放虚拟用户. 注意:此选项将会干扰场景的计划.如果选择 ...

  8. 解决ValueError: Error initializing torch.distributed using env:// rendezvous:: environment variable 报错

    在命令行运行程序时候可成功跑通,但在程序调试过程中出现如下错误: 源代码: 修改后: import torch.distributed as dist import os os.environ['MA ...

  9. java 定时器获得外部参数_JMeter定时器使用小结

    一.定时器的作用域 1.无论定时器位置在Sampler之前还是下面,定时器是在每个sampler(采样器)之前执行的,而不是之后: 2.当执行一个Sampler之前时,所有当前作用域内的定时器都会被执 ...

  10. Request Connection: Remote Server @ 192.229.145.200:80

    录制Loadrunner脚本时,提示: Request Connection: Remote Server @ 192.229.145.200:80   NOT INTERCEPTED!(REASON ...

最新文章

  1. oracle 关系 表 视图_oracle动态视图v$,v_$,gv$,gv_$与x$之间的关系
  2. HDFS设计思路,HDFS使用,查看集群状态,HDFS,HDFS上传文件,HDFS下载文件,yarn web管理界面信息查看,运行一个mapreduce程序,mapreduce的demo...
  3. linux uniq命令_如何在Linux上使用uniq命令
  4. .net core i上 K8S(四).netcore程序的pod管理,重启策略与健康检查
  5. 在Windows运行Python程序
  6. 详解Mysql中的JSON系列操作函数
  7. LeetCode题解
  8. 入门 | 关于神经网络:你需要知道这些
  9. HOW TO:在 Visual C++ .NET 中从 System::String* 转换为 Char*
  10. Windows判断是否为64位程序(C++)
  11. POJ 1001 Exponentiation
  12. 云计算的安全顾虑中不透明性影响云落地
  13. js系列教程6-BOM操作全解
  14. nxp单片机入门_使用恩智浦MCUXpresso开发FRDM-KL46Z入门
  15. java 文件上传(使用多线程)
  16. c语言等差数列试题及其答案,等差数列练习题
  17. 一个女人应该如何生活
  18. STM32WB55_NUCLEO开发(8)----授权
  19. 淘淘商城项目---8.5
  20. 计算机一直重启无法进入系统,电脑进不了系统一直重启怎么处理

热门文章

  1. win2012R2无法打开匿名级安全令牌,安装.net 3.5
  2. linux 检测SSD寿命
  3. LM317稳压芯片在工程中的应用
  4. kafka不消费:9092 (id: 0 rack: null)
  5. python开发网页视频播放器_python实现媒体播放器功能
  6. 【牛刀小试4】斐波那契数
  7. 计算机相关课程考核,计算机专业编程实践类课程考核方法
  8. 朗兰兹纲领:关于数学大一统的伟大构想
  9. 数学最高奖菲尔兹奖得主加入华为!研究数学大一统理论,任正非曾说“国家若要强盛,数学是基础”...
  10. STM32 LoRaWAN探索板B-L072Z-LRWAN1入门指南