给你一个图和三个点U,V,W  问你是否存在从U到V和从U到W的两条边不相交路径

先边双缩点 再每个连通分量搞LCA 最后LCA判

#include<bits/stdc++.h>
using namespace std;
#define INF 0xfffffff
#define maxn 200025
#define min(a,b) (a<b?a:b)
int m, n, Time, cnt, top;
int dfn[maxn], block[maxn], low[maxn], Father[maxn], Stack[maxn];
int Bcc[maxn], Bcccnt = ;
vector<int> G[maxn], G2[maxn];
inline void read(int &v) {
v = ;
char c = ;
int p = ;
while (c < '' || c > '') {
if (c == '-') {
p = -;
}
c = getchar();
}
while (c >= '' && c <= '') {
v = (v << ) + (v << ) + c - '';
c = getchar();
}
v *= p;
}
void Tarjan(int u, int fa) {
dfn[u] = low[u] = ++Time;
Father[u] = fa;
Stack[top++] = u;
int len = G[u].size(), v, k = ;
for (int i = ; i < len; i++) {
v = G[u][i];
if (v == fa && !k) {
k ++;
continue;
}
if (!low[v]) {
Tarjan(v, u);
low[u] = min(low[u], low[v]);
} else {
low[u] = min(low[u], dfn[v]);
}
}
if (dfn[u] == low[u]) {
do {
v = Stack[--top];
block[v] = cnt;
} while (u != v);
cnt ++;
}
}
void getBcc(int x, int y) {
Bcc[x] = y;
for (auto v : G[x]) {
if (Bcc[v] == ) {
getBcc(v, y);
}
}
}
int T;
int q, N;
int u, v, c, w; typedef struct {
int from, to, w;
} edge; //这个结构体用来存储边
vector<edge> edges;
//保存边的数组
int grand[maxn][]; //x向上跳2^i次方的节点,x到他上面祖先2^i次方的距离
int depth[maxn];//深度
int root;
bool vis[maxn];
void addedge(int x, int y, int w) { //把边保存起来的函数
edge a = {x, y, w}, b = {y, x, w};
edges.push_back(a);
edges.push_back(b);
G2[x].push_back(edges.size() - );
G2[y].push_back(edges.size() - );
}
void dfs(int x) { //dfs建图
vis[x] = ;
for (int i = ; i <= N; i++) { //第一个几点就全部都是0,第二个节点就有变化了,不理解的话建议复制代码输出下这些数组
grand[x][i] = grand[grand[x][i - ]][i - ]; //倍增 2^i=2^(i-1)+2^(i-1)
}
for (int i = ; i < G2[x].size(); i++) {
edge e = edges[G2[x][i]];
if (e.to != grand[x][]) { //这里我们保存的是双向边所以与他相连的边不是他父亲就是他儿子父亲的话就不能执行,不然就死循环了。
depth[e.to] = depth[x] + ; //他儿子的深度等于他爸爸的加1
grand[e.to][] = x; //与x相连那个节点的父亲等于x
//gwmax[e.to][0]=e.w;
dfs(e.to);//深搜往下面建
}
}
}
int lca(int a, int b) {
if (a == b) {
return a;
}
if (depth[a] > depth[b]) {
swap(a, b); //保证a在b上面,便于计算
}
for (int i = N; i >= ; i--) { //类似于二进制拆分,从大到小尝试
if (depth[a] < depth[b] && depth[grand[b][i]] >= depth[a]) { //a在b下面且b向上跳后不会到a上面
b = grand[b][i]; //先把深度较大的b往上跳
}
}
if (a == b) {
return a;
}
for (int j = N; j >= ; j--) { //在同一高度了,他们一起向上跳,跳他们不相同节点,当全都跳完之后grand【a】【0】就是lca,上面有解释哈。
if (grand[a][j] != grand[b][j]) {
a = grand[a][j];
b = grand[b][j];
}
}
if (grand[a][] == && grand[b][] == && a != b) {
return -;
}
return grand[a][];
} void init(int n) {
edges.clear();
Bcccnt = cnt = ;
top = Time = ;
for (int i = ; i <= n; i++) {
vis[i] = dfn[i] = low[i] = block[i] = Father[i] = Bcc[i] = ;
G[i].clear();
G2[i].clear();
}
}
int main() {
read(T);
while (T--) {
read(n), read(m), read(q);
init(n + );
for (int i = ; i <= m; i++) {
read(u), read(v);
if (u != v) {
G[u].push_back(v);
G[v].push_back(u);
}
}
for (int i = ; i <= n; i++) {
if (Bcc[i] == ) {
getBcc(i, Bcccnt);
Bcccnt++;
}
}
for (int i = ; i <= n; i++) {
if (!low[i]) {
Tarjan(i, i);
}
}
depth[] = -;
N = floor(log(cnt + 0.0) / log(2.0)) + ; //最多能跳的2^i祖先
for (int i = ; i <= n; i++) {
v = Father[i];
if (block[i] != block[v]) {
addedge(block[i], block[v], );
}
}
for (int i = ; i < cnt; i++) {
if (!vis[i]) {
depth[i] = ;
root = i;
dfs(root);
}
}
for (int i = ; i <= q; i++) {
read(u), read(v), read(w);
if (Bcc[u] != Bcc[v] || Bcc[u] != Bcc[w]) {
printf("No\n");
continue;
}
u = block[u], v = block[v], w = block[w];
if (u == v || u == w) {
printf("Yes\n");
continue;
}
if (v == w) {
printf("No\n");
continue;
}
int t[] = {u, lca(u, w), lca(u, v), lca(v, w)};
sort(t, t + , [](int x, int y) {
return depth[x] < depth[y];
});
if (t[] == u && t[] == u) {
printf("Yes\n");
} else {
printf("No\n");
}
}
}
return ;
}

ZOJ 4097 Rescue the Princess 边双缩点+LCA的更多相关文章

  1. ZOJ 4097 Rescue the Princess

    在这个物欲横流的社会 oj冷漠无情 只有这xx还有些温度 越界就越界吧  wrong 怎么回事.... 给出一个图 然后给出q次询问 问是否存在v和w分别到u的路径且边不重复 在边双连通分量中 任意两 ...

  2. POJ3694 Network 边双缩点+LCA+并查集

    辣鸡错误:把dfs和ldfs搞混...QAQ 题意:给定一个无向图,然后查询q次,求每次查询就在图上增加一条边,求剩余割边的个数. 先把边双缩点,然后预处理出LCA的倍增数组: 然后加边时,从u往上跳 ...

  3. H - Rescue the Princess ZOJ - 4097 (tarjan缩点+倍增lca)

    题目链接: H - Rescue the Princess  ZOJ - 4097 学习链接: zoj4097 Rescue the Princess无向图缩点有重边+lca - lhc..._博客园 ...

  4. Day10 - A - Rescue the Princess ZOJ - 4097

    Princess Cjb is caught by Heltion again! Her knights Little Sub and Little Potato are going to Helti ...

  5. sdut 2603:Rescue The Princess(第四届山东省省赛原题,计算几何,向量旋转 + 向量交点)

    Rescue The Princess Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 Several days ago, a b ...

  6. 山东省第四届acm.Rescue The Princess(数学推导)

    Rescue The Princess Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 412  Solved: 168 [Submit][Status ...

  7. 计算几何 2013年山东省赛 A Rescue The Princess

    题目传送门 /* 已知一向量为(x , y) 则将它旋转θ后的坐标为(x*cosθ- y * sinθ , y*cosθ + x * sinθ) 应用到本题,x变为(xb - xa), y变为(yb ...

  8. sdutoj 2603 Rescue The Princess

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2603 Rescue The Princess ...

  9. SDUT 2603:Rescue The Princess

    Rescue The Princess Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 Several days ago, a b ...

随机推荐

  1. Qt——鼠标拖动缩放窗口源码

    #ifndef MOVEWIDGET_H #define MOVEWIDGET_H #include <QWidget> #include <QEvent> class Mov ...

  2. Django模板及表查询笔记

    模板层 后端朝html页面传递数据 两种给html页面传递数据的方式 第一种: render(request,'index.html',{'user_list':user_list}) 第二种 ren ...

  3. 使用Dreamweaver制作简单网站(二)

    继续上周没完成的 一.新建iframe.css 1.点击文件-选择新建-css 2.ctrl+s保存为iframe.css 在style文件夹下. 3.回到main.html 右键选择-附加样式表,选 ...

  4. Design Excel Sum Formula

    Your task is to design the basic function of Excel and implement the function of sum formula. Specif ...

  5. windows 修改Administrator管理员账户名

      用[Win+R]组合键命令打开[运行]界面,输入[gpedit.msc],按[回车键]或[鼠标左键]单击[确定]按钮:   在弹出的[本地组策略编辑器]对话框中,依次[鼠标左键]点击打开:[计算机 ...

  6. MySQL中的InnoDB中产生的死锁深究

    查考地址:https://blog.csdn.net/loophome/article/details/79867174 待研究中.....

  7. Mybatis Plus带多条件的多表联合、分页、排序查询

    目录 一.现有表 student学生表: facultylist学院表: 二.同时满足以下需求: 1.多表联合查询出学院名字 2.可以带多条件查询 3.指定页码,页数据大小进行物理分页查询 三.解决步 ...

  8. fiddler笔记:Composer选项卡

    1.Composer选项卡介绍 Composer选项卡功能是可以手动构建和发送HTTP.HTTPS和FTP请求. 支持将Web Session列表中选中的Session拖入Composer选项卡,然后 ...

  9. C++反汇编第三讲,反汇编中识别继承关系,父类,子类,成员对象

    讲解目录: 1.各类在内存中的表现形式   备注: 主要复习开发知识,和反汇编没有关系,但是是理解反汇编的前提.     2.子类继承父类 2.1 子类中有虚函数,父类中有虚函数 : 都有的情况下   ...

  10. css鼠标悬浮控制元素隐藏与显示

    在网页开发中经常有需求是鼠标移动到一个元素A身上时,另外一个元素B显示. 如下图 当鼠标移到图片上时,相关的描述从下方显示出来. css实现原理与情景: A 是 B 的父元素 B 默认隐藏 B{opa ...