Solution -「洛谷 P4320」道路相遇
\(\mathcal{Description}\)
Link.
给定一个 \(n\) 个点 \(m\) 条边的连通无向图,并给出 \(q\) 个点对 \((u,v)\),询问 \(u\) 到 \(v\) 的路径所必经的结点个数。
\(n,q\le5\times10^5\),\(q\le\min\{\frac{n(n-1)}2,10^6\}\)。
\(\mathcal{Solution}\)
大概是双倍经验吧。
建出圆方树,预处理圆方树上每个点到根经过的圆点个数,然后求 LCA 计算答案即可。
复杂度 \(\mathcal O(n\log n)-\mathcal O(\log n)\)。
\(\mathcal{Code}\)
#include <cstdio>
const int MAXN = 5e5, MAXM = 1e6;
int n, m, q, snode;
int dfc, top, dfn[MAXN + 5], low[MAXN + 5], stk[MAXN + 5];
int dep[MAXN * 2 + 5], cnt[MAXN * 2], fa[MAXN * 2 + 5][20];
struct Graph {
int ecnt, head[MAXN * 2 + 5], to[MAXM * 2 + 5], nxt[MAXM * 2 + 5];
inline void link ( const int s, const int t ) {
to[++ ecnt] = t, nxt[ecnt] = head[s];
head[s] = ecnt;
}
inline void add ( const int u, const int v ) {
link ( u, v ), link ( v, u );
}
} src, tre;
inline bool chkmin ( int& a, const int b ) { return b < a ? a = b, true : false; }
inline void Tarjan ( const int u, const int f ) {
dfn[u] = low[u] = ++ dfc, stk[++ top] = u;
for ( int i = src.head[u], v; i; i = src.nxt[i] ) {
if ( ( v = src.to[i] ) == f ) continue;
if ( ! dfn[v] ) {
Tarjan ( v, u ), chkmin ( low[u], low[v] );
if ( low[v] >= dfn[u] ) {
tre.add ( u, ++ snode );
do tre.add ( snode, stk[top] ); while ( stk[top --] ^ v );
}
} else chkmin ( low[u], dfn[v] );
}
}
inline void init ( const int u, const int f ) {
dep[u] = dep[fa[u][0] = f] + 1, cnt[u] = cnt[f] + ( u <= n );
for ( int i = 1; i <= 19; ++ i ) fa[u][i] = fa[fa[u][i - 1]][i - 1];
for ( int i = tre.head[u], v; i; i = tre.nxt[i] ) {
if ( ( v = tre.to[i] ) ^ f ) {
init ( v, u );
}
}
}
inline int calcLCA ( int u, int v ) {
if ( dep[u] < dep[v] ) u ^= v ^= u ^= v;
for ( int i = 19; ~ i; -- i ) if ( dep[fa[u][i]] >= dep[v] ) u = fa[u][i];
if ( u == v ) return u;
for ( int i = 19; ~ i; -- i ) if ( fa[u][i] ^ fa[v][i] ) u = fa[u][i], v = fa[v][i];
return fa[u][0];
}
int main () {
scanf ( "%d %d", &n, &m ), snode = n;
for ( int i = 1, u, v; i <= m; ++ i ) {
scanf ( "%d %d", &u, &v );
src.add ( u, v );
}
Tarjan ( 1, 0 ), init ( 1, 0 );
scanf ( "%d", &q );
for ( int i = 1, u, v; i <= q; ++ i ) {
scanf ( "%d %d", &u, &v );
int w = calcLCA ( u, v );
printf ( "%d\n", cnt[u] + cnt[v] - cnt[w] - cnt[fa[w][0]] );
}
return 0;
}
Solution -「洛谷 P4320」道路相遇的更多相关文章
- Solution -「洛谷 P4372」Out of Sorts P
\(\mathcal{Description}\) OurOJ & 洛谷 P4372(几乎一致) 设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...
- Note/Solution -「洛谷 P5158」「模板」多项式快速插值
\(\mathcal{Description}\) Link. 给定 \(n\) 个点 \((x_i,y_i)\),求一个不超过 \(n-1\) 次的多项式 \(f(x)\),使得 \(f(x ...
- Solution -「洛谷 P4198」楼房重建
\(\mathcal{Description}\) Link. 给定点集 \(\{P_n\}\),\(P_i=(i,h_i)\),\(m\) 次修改,每次修改某个 \(h_i\),在每次修改后 ...
- Solution -「洛谷 P6577」「模板」二分图最大权完美匹配
\(\mathcal{Description}\) Link. 给定二分图 \(G=(V=X\cup Y,E)\),\(|X|=|Y|=n\),边 \((u,v)\in E\) 有权 \(w( ...
- Solution -「洛谷 P6021」洪水
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个点的带点权树,删除 \(u\) 点的代价是该点点权 \(a_u\).\(m\) 次操作: 修改单点点权. ...
- Solution -「洛谷 P4719」「模板」"动态 DP" & 动态树分治
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个结点的带权树,\(m\) 次单点点权修改,求出每次修改后的带权最大独立集. \(n,m\le10^5 ...
- Solution -「洛谷 P5236」「模板」静态仙人掌
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的仙人掌,\(q\) 组询问两点最短路. \(n,q\le10^4\),\(m\ ...
- Solution -「洛谷 P5827」边双连通图计数
\(\mathcal{Description}\) link. 求包含 \(n\) 个点的边双连通图的个数. \(n\le10^5\). \(\mathcal{Solution}\) ...
- Solution -「洛谷 P5827」点双连通图计数
\(\mathcal{Description}\) link. 求有 \(n\) 个结点的点双连通图的个数,对 \(998244353\) 取模. \(n\le10^5\). \(\mat ...
随机推荐
- sqlplus -S参数表示什么意思?
sqlplus -S , -S选项是静默模式,是Silent的缩写.在这种模式下将会以最精简的形式完成SQL*Plus的交互过程. -S模式多用于脚本模式.在命令行sqlplus -S还有可能出现卡住 ...
- nuxt2.0项目创建(最新)
使用import需要babel编译写法如下 //修改1打开package.json文件 "dev": "cross-env NODE_ENV=development n ...
- ES6常用知识点
一.变量 var:定义的变量有时候会成为全局变量 let:定义的变量严格,只在代码块内有效 const:声明的变量是常量,不能被修改 二.数据类型 字符串 @定义:~字符串定义标记,支持换行. #常 ...
- 学习笔记--Java中的变量
Java中的变量 /** * 关于 Java 语言当中的变量: * * 1. 什么是变量? * - 变量的本质上来说是内存空间,这块空间有(数据类型.名字.字面值) * - 变量包括三部分:数据类型. ...
- vue3 watch和watchEffect的详细讲解
watch 监听 reative 创建的值 const state = reactive({ nickname: "xiaofan", age: 20 }); setTimeout ...
- yum安装软件时,出现"No package XXX available"的解决办法
第一种: 依次执行以下命令解决 1,cd /home 2,wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noa ...
- 【PTA】字符串正反序连接
将s所指字符串的正序和反序进行连接,形成一个新串放在t所指的数组中. 函数接口定义: void fun (char *s, char *t); 其中s 和t都是用户传入的参数.函数将s所指字符串的正序 ...
- rocketmq实现延迟队列精确到秒级实现(总结编)
前言篇: 为了节约成本,决定通过自研来改造rocketmq,添加任意时间延迟的延时队列,开源版本的rocketmq只有支持18个等级的延迟时间, 其实对于大部分的功能是够用了的,但是以前的项目,全部都 ...
- python测试框架-pytest
一.pytest 介绍.运行.参数化和数据驱动.Fixture pytest安装与介绍 官网 : pip install -U pytest 查看版本号:pytest --version 为何选择py ...
- C# 获取DPI例子
public static float GetDpiX() { System.Windows.Forms.Panel p = new System.Windows.Forms.Panel(); Sys ...