题目大意:基本同上一题[bzoj5329][Sdoi2018]战略游戏,只是每个点集内只有两个点,且只有一组询问而已。(双倍经验?我反正就直接改了一下代码就交了)

题解:同上一题(链接见“题目大意”)

卡点:

C++ Code:

#include <cstdio>
#include <cstring>
#define maxn 1000010
#define maxm 1000010
int Tim, n, m, LCA;
inline int min(int a, int b) {return a < b ? a : b;}
inline void swap(int &a, int &b) {a ^= b ^= a ^= b;}
struct Tree {
#define root 1
#define fa(u) dad[u][0]
#define M 18
int head[maxn], cnt;
struct Edge {
int to, nxt;
} e[maxm << 1];
inline void addE(int a, int b) {e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;}
inline void add(int a, int b) {
addE(a, b);
addE(b, a);
} int dad[maxn][M], dep[maxn], sz[maxn];
int dfn[maxn], idx;
void dfs(int u = root) {
dfn[u] = ++idx;
for (int i = 1; i < M; i++) dad[u][i] = dad[dad[u][i - 1]][i - 1];
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != fa(u)) {
sz[v] = sz[u] + int(v <= n);
// printf("link %d %d\n", v, sz[v]);
dep[v] = dep[u] + 1;
fa(v) = u;
dfs(v);
}
}
}
inline int LCA(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
for (int i = dep[x] - dep[y]; i; i &= i - 1) x = dad[x][__builtin_ctz(i)];
if (x == y) return x;
for (int i = M - 1; ~i; i--) if (dad[x][i] != dad[y][i]) x = dad[x][i], y = dad[y][i];
return fa(x);
} inline int len(int x, int y) {
return sz[x] + sz[y] - (sz[::LCA = LCA(x, y)] << 1);
} inline void init() {
memset(head, 0, sizeof head); cnt = 0;
memset(dfn, 0, sizeof dfn); idx = 0;
sz[root] = 0;
}
#undef root
#undef fa
#undef M
} T; struct Graph {
#define root 1
int head[maxn], cnt;
struct Edge {
int to, nxt;
} e[maxm << 1];
inline void addE(int a, int b) {e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;}
inline void add(int a, int b) {
addE(a, b);
addE(b, a);
} int DFN[maxn], low[maxn], idx, CNT;
int S[maxn], top, tmp;
void tarjan(int u = root) {
DFN[u] = low[u] = ++idx;
S[++top] = u;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (!DFN[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
if (low[v] >= DFN[u]) {
CNT++;
T.add(CNT, u);
do {
T.add(CNT, tmp = S[top--]);
} while (tmp != v);
}
} else low[u] = min(low[u], DFN[v]);
}
} inline void init(int n) {
memset(head, 0, sizeof head); cnt = 0;
memset(DFN, 0, sizeof DFN); idx = 0;
CNT = n;
}
#undef root
} G; #define OnlineJudge
#define read() R::READ()
#include <cctype>
namespace R {
int x;
#ifdef Online_Judge
char *ch, op[1 << 26];
inline void init() {
fread(ch = op, 1, 1 << 26, stdin);
}
inline int READ() {
while (isspace(*ch)) ch++;
for (x = *ch & 15, ch++; isdigit(*ch); ch++) x = x * 10 + (*ch & 15);
return x;
}
#else
char ch;
inline int READ() {
ch = getchar();
while (isspace(ch)) ch = getchar();
for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15);
return x;
}
#endif
} int main() {
#ifdef Online_Judge
R::init();
#endif
G.init(n = read()), T.init();
for (int i = m = read(); i; i--) G.add(read(), read());
G.tarjan();
T.dfs();
int Q = read();
while (Q --> 0) printf("%d\n", T.len(read(), read()) + int(LCA <= n));
return 0;
}

[洛谷P4320]道路相遇的更多相关文章

  1. 【刷题】洛谷 P4320 道路相遇

    题目描述 在 H 国的小 w 决定到从城市 \(u\) 到城市 \(v\) 旅行,但是此时小 c 由于各种原因不在城市 \(u\),但是小 c 决定到在中途与小 w 相遇 由于 H 国道路的原因,小 ...

  2. 【题解】洛谷P1070 道路游戏(线性DP)

    次元传送门:洛谷P1070 思路 一开始以为要用什么玄学优化 没想到O3就可以过了 我们只需要设f[i]为到时间i时的最多金币 需要倒着推回去 即当前值可以从某个点来 那么状态转移方程为: f[i]= ...

  3. 洛谷 P3905 道路重建

    题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现在有两个重要城市A和B ...

  4. 【洛谷 P4320】 道路相遇 (圆方树,LCA)

    题目链接 题意:给一张无向图和\(M\)个询问,问\(u,v\)之间的路径的必经之点的个数. 对图建出圆方树,然后必经之点就是两点路径经过的原点个数,用\((dep[u]+dep[v]-dep[LCA ...

  5. Solution -「洛谷 P4320」道路相遇

    \(\mathcal{Description}\)   Link.   给定一个 \(n\) 个点 \(m\) 条边的连通无向图,并给出 \(q\) 个点对 \((u,v)\),询问 \(u\) 到 ...

  6. 洛谷 [HNOI2014]道路堵塞 解题报告

    [HNOI2014]道路堵塞 题意 给一个有向图并给出一个这个图的一个\(1\sim n\)最短路,求删去这条最短路上任何一条边后的最短路. 又事SPFA玄学... 有个结论,新的最短路一定是\(1\ ...

  7. 洛谷P1070 道路游戏(dp+优先队列优化)

    题目链接:传送门 题目大意: 有N条相连的环形道路.在1-M的时间内每条路上都会出现不同数量的金币(j时刻i工厂出现的金币数量为val[i][j]).每条路的起点处都有一个工厂,总共N个. 可以从任意 ...

  8. 洛谷 P1070 道路游戏 解题报告

    P1070 道路游戏 题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有\(n\)个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依 ...

  9. 洛谷——P3905 道路重建

    P3905 道路重建 题目描述 从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连.在经过一次严重的战争之后,有d条道路被破坏了.国王想要修复国家的道路系统,现 ...

随机推荐

  1. Java分享笔记:使用缓冲流复制文件

    [1] 程序设计 /*------------------------------- 1.缓冲流是一种处理流,用来加快节点流对文件操作的速度 2.BufferedInputStream:输入缓冲流 3 ...

  2. Shell 入门笔记(一)

    Shell简介 在开发过程中Linux系统经常接触和使用的,Shell 是我们用户使用 Linux 的桥梁,是C 语言编写的程序.Shell 是一种命令语言,同时一种程序设计语言.对大多数开发人员来说 ...

  3. IDEA的下载安装和激活

    1.下载网站http://www.jetbrains.com/ 2. 3. 4.注意要下载Ultimate版本 5.安装 下载完成后直接下一步,傻瓜式安装 6.激活,在图片位置输入激活码即可 !!!! ...

  4. React路由-进阶篇

    路由进阶 1.多级路由,和之前的思想一样,在子路由里面继续写Route,继续挂载组件,就可以实现多级路由 比如这样:class Food extends Component{ render() { r ...

  5. OSI七层模型 学习摘要

    OSI参考模型是计算机网路体系结构发展的产物.它的基本内容是开放系统通信功能的分层结构.这个模型把开放系统的通信功能划分为七个层次,从邻接物理媒体的层次开始,分别赋于1,2,……7层的顺序编号,相应地 ...

  6. vue 改变我们插值的符号{{}}改为${}

    delimiters的作用是改变我们插值的符号.Vue默认的插值是双大括号{{}}.但有时我们会有需求更改这个插值的形式. delimiters:['${','}'] 现在我们的插值形式就变成了${} ...

  7. 学习python第十二天,函数4 生成器generator和迭代器Iterator

    在Python中,这种一边循环一边计算的机制,称为生成器:generator 要创建一个generator,有很多种方法.第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个genera ...

  8. B1076 Wifi密码 (15分)

    B1076 Wifi密码 (15分) 下面是微博上流传的一张照片:"各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1:B ...

  9. Git ---游离状态下的commit 分支切换与找回,commit之后无法找到历史记录

    commit之后无法找到历史记录 https://blog.csdn.net/zyb2017/article/details/78307688

  10. 学习网络请求返回json对应的model

    原来泛型可以这样用: 网络返回基类,返回一个code,msg,body,其中body不确定,所以,我们把它写成泛型 import org.json.JSONObject; /** * 网络请求的基类 ...