给你一个图和三个点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. spring的控制器如何跳转到指定的视图

    1.控制器代码 2.跳转代码 return "greeting"; 引号内为跳转的页面,默认不需要加html

  2. Android使用glide加载.9图片的方法

    我们在开发过程中会经常使用.9图片, 因为它可以使图片拉伸的时候,保证其不会失真. 而我们把.9图片放在服务器端,通过glide直接加载,会报错. 我们的解决方法是 通过sdk的aapt工具 把.9图 ...

  3. 利用js对象将iframe数据缓存, 实现子页面跳转后, 返回时不丢失之前填写的数据

    利用js对象将iframe数据缓存, 实现子页面跳转后, 返回时不丢失之前填写的数据 实现描述:将数据存放在js对象中, 然后放在父页面的document对象中, 在页面刷新的时候将父页面的值取出来, ...

  4. Win7 Eclipse 搭建spark java1.8(lambda)环境:WordCount helloworld例子

    [学习笔记] Win7 Eclipse 搭建spark java1.8(lambda)环境:WordCount helloworld例子 lambda表达式是java8给我们带来的一个重量的新特性,借 ...

  5. 【AtCoder】AGC008

    AGC008 A - Simple Calculator 如果符号相同,那么如果y比x大直接走,否则需要两次反号 如果符号不同,需要绝对值的差加一次反号 如果有一个是0,且y比x要小,那只需要一次反号 ...

  6. RabbitMQ快速开始

    ①:安装rabbitmq所需要的依赖包 yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make g ...

  7. S02_CH10_ User GPIO实验

    S02_CH10_ User GPIO实验 在之前的第四章课程中,我们详细的讲解了如何在VIVADO软件下封装一个简单的流水灯程序.在ZYNQ开发过程中,有时候我们可能会需要与ARM硬核进行通信,在这 ...

  8. hdu 6069 Counting divisors 公式+区间筛

    比赛的时候把公式扣出来了,,但是没有想到用筛法算公因子,,默默学习一下.. 题解:设n=p1^(c1)p2^{c2}...pm^{cm},n=p​1^​c​1*​​​​p​2​^c​2​​​​...p ...

  9. MongoDB的复合唯一索引

    一 创建 JavaScript Shell db.room.ensureIndex({'floor':1,'num':1}) Spring Data @Data // lombok @Document ...

  10. ajax 请求二进制流 图片

    <html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    ...