P3533

news/2025/3/20 22:00:31/文章来源:https://www.cnblogs.com/houpingze/p/18784065

P3533 [POI 2012] RAN-Rendezvous

题目描述

译自 POI 2012 Stage 1. 「Rendezvous」

给定一个有 \(n\) 个顶点的有向图,每个顶点有且仅有一条出边。每次询问给出两个顶点 \(a_i\)\(b_i\),求满足以下条件的 \(x_i\)\(y_i\)

  • 从顶点 \(a_i\) 沿出边走 \(x_i\) 步与从顶点 \(b_i\) 沿出边走 \(y_i\) 步到达的顶点相同。
  • \(\max(x_i, y_i)\) 最小。
  • 满足以上条件的情况下 \(\min(x_i, y_i)\) 最小。
  • 如果以上条件没有给出一个唯一的解,则还需要满足 \(x_i \ge y_i\).

如果不存在这样的 \(x_i\)\(y_i\),则 \(x_i = y_i = -1\).

输入 #1

12 5
4 3 5 5 1 1 12 12 9 9 7 1
7 2
8 11
1 2
9 10
10 5

输出 #1

2 3
1 2
2 2
0 1
-1 -1

对于 \(100\%\) 的数据,\(1 \le n \le 500\ 000,1 \le k \le 500\ 000\).

若两个点所在连通图里面没有环,则显然答案就是LCA

如果有环,分两种情况讨论

  1. 两个点都在环上面
  2. 两个点都不在环上面
  3. 其中一个点在环上面

为了方便判断,直接写一个 check 函数即可。
代码比较阴间。

#include<bits/stdc++.h>
#define N 505050
#define rep(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
int cnt[N],n,m,fa[N][22],len[N],R[1114514];
int tot;
vector<int>G[N];
int root[1145141];
int dep[1145141],step[1145141];
void dfs(int u,int f,int rt) {dep[u]=dep[f]+1;root[u]=rt;for(int i=0;i<G[u].size();i++) {int v=G[u][i];if(cnt[v]||v==f) continue;dfs(v,u,rt);}
}inline int read() {int res=0,fs=1;char c=getchar();while(!(c>='0'&&c<='9')) {if(c=='-') fs=-1;c=getchar();}while(c>='0'&&c<='9') {res=res*10+c-'0';c=getchar();}return res*fs;
}int lca(int x,int y) {if(dep[x]<dep[y]) swap(x,y);int tmp=dep[x]-dep[y];for(int i=19;i>=0;i--) {if(tmp>>i&1) x=fa[x][i];}if(x==y) return y;for(int i=19;i>=0;i--) {if(fa[x][i]!=fa[y][i]) {x=fa[x][i];y=fa[y][i];}}return fa[x][0];
}bool check(int a,int b,int c,int d){if(max(a,b)!=max(c,d))return max(a,b)<max(c,d);if(min(a,b)!=min(c,d))return min(a,b)<min(c,d);return a>=b;
}
void round(int u,int id,int st) {if(step[u]) return ;R[u]=id;len[id]++;step[u]=st;round(fa[u][0],id,st+1);
}
signed main() {cin>>n>>m;for(int i=1;i<=n;i++) {int u=read();G[u].push_back(i);fa[i][0]=u;cnt[u]++;}queue<int>q;rep(i,1,n) if(!cnt[i]) q.push(i); while(!q.empty()) {int u=q.front();q.pop();int v=fa[u][0];cnt[v]--;if(cnt[v]==0) q.push(v);}rep(i,1,n) {if(cnt[i]) {dfs(i,0,i);if(!step[i]) {tot++;round(i,tot,1);}}}rep(p,1,19)rep(i,1,n){ fa[i][p]=fa[fa[i][p-1]][p-1];}while(m--) {int u=read(),v=read();if(R[root[u]]!=R[root[v]]){cout<<-1<<' '<<-1<<'\n';} else if(root[u]==root[v]) {int l=lca(u,v);cout<<dep[u]-dep[l]<<' '<<dep[v]-dep[l]<<'\n';} else {int t1=root[u],t2=root[v];int ans1=dep[u]+(step[t2]-step[t1]+len[R[t1]])%len[R[t1]],ans2=dep[v]+(step[t1]-step[t2]+len[R[t1]])%len[R[t1]];if(check(dep[u],ans2,ans1,dep[v]))cout<<dep[u]-1<<' '<<ans2-1<<endl;else cout<<ans1-1<<' '<<dep[v]-1<<endl;}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/902232.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

L1 通讲

好多,好多。L1 通讲 部分知识点速通 技术与产品开发的动机 ​ 这张图展示了两个长期趋势:技术和创新的发展速度逐渐变快; 它对我们的生活影响非常广泛,包括好的(如天花疫苗)和坏的(核弹?) 技术变得越来越强大。 例如,我们的祖先使用石制工具,但现在我们构建跨越全球…

Flink 实战之流式数据去重

流式数据是一种源源不断产生的数据,没有预定的开始与结束,至少理论上来说,它的数据输入永远不会结束。因此流式数据处理与传统的批处理技术不同,必须具备持续不断地对到达的数据进行处理的能力。因为流式数据源源不断地产生,对流式数据做去重就十分困难,因为一条数据重复…

vue3 + springboot 实现模糊查询与增加操作

实现表格查询: <!-- 表格 --><div class="card" style="margin-bottom: 5px"><el-table :data="data.tableData" stripe><el-table-column label="名称" prop="name" /><el-table-column lab…

网络基础与进阶

计算机网络入门与进阶 学习OSI网络模型相关概念(重点掌握) 学习TCP三次握手与四次挥手过程(重点掌握) 学习TCP的11种状态集转化(重点掌握) 学习DNS相关知识概念与原理 linux网关配置(添加网关 网段 以及网络主机路由) 修改网卡配置文件 用户访问www.baidu.com 整个过程…

VTK-8.2.0源码编译和初步使用(Cmake+VS2015+Qt5.14.2)

一、准备数据 1、首先确保已安装VS5015和Qt5.14.2 2、下载Cmake并安装:Download CMake 3、下载VTK-8.2.0源码和数据并解压:Download | VTK 二、Cmake构建 1、在本地磁盘创建相关文件夹2、进入源码根目录,找到CmakeList.txt,修改CmakeList.txt中的选项,使得Debug模式下生成…

B2043 判断能否被3,5,7整除

读者自己完善一下10、11、13、14行吧

20244113 实验一《Python程序设计》实验报告

课程:《Python程序设计》 班级: 2441 姓名: 咸润杰 学号:20244113 实验教师:王志强 实验日期:2025年3月20日 必修/选修: 公选课 1.实验内容 (1)熟悉Python开发环境; (2)下载python与pycharm,完成python开发环境搭建; (3)编写程序,练习变量和类型、字符串、对象…

P8435 【模板】点双连通分量

P8435 【模板】点双连通分量 题目描述 对于一个 \(n\) 个节点 \(m\) 条无向边的图,请输出其点双连通分量的个数,并且输出每个点双连通分量。 输入格式 第一行,两个整数 \(n\) 和 \(m\)。 接下来 \(m\) 行,每行两个整数 \(u, v\),表示一条无向边。 输出格式 第一行一个整数…

SqlServer 中行转列PIVOT函数用法

SqlServer 中行转列PIVOT函数用法 前言 最近在面试的时候,碰到了手写sql的题目,这让我这个面向AI的程序员着实难看。只见我面露难色,绞尽脑汁的情况下,终于还是放弃了。 这道题目不难,但是由于平时几乎没有遇到行转列的情况,导致在手写时忘记了PIVOT函数怎么使用😩。 面…

第五周第四天

所用时间:180分钟 代码量(行):15 博客量(篇):1 了解到的知识点: 1.matplotlib的配置 因为要参加数学建模大赛,今天配置了python和matplotlib环境,尝试运行了程序,代码如下: import matplotlib.pyplot as plt import numpy as np# 生成数据 x = np.linspace(0, 10, …

Vue3中使用TinyMce编辑器

Vue3中使用TinyMce编辑器 - 知乎 一,安装TinyMce富文本vue npm install @tinymce/tinymce-vue -S npm install tinymce -STinyMce本身是英文编辑器,所以还需要下载中文本地化文件:https://www.tiny.cloud/get-tiny/language-packages/下载完成后放入node_modules下的tinymce…