P4334 [COI2007] Policija

题意

一个无重边的无向图,每次询问删掉一条边或删掉一个点后两个点是否联通。

思路

连通性问题,我们可以考虑使用广义圆方树解决。

  1. 对于删掉一个点的情况:

我们先跑 tarjan 建出圆方树。如何判断两点在删去一个点后在树上的连通性?当且仅当被删去的点在两点间的路径上。根据圆方树的性质,如果被删点在一个点双连通分量中,它是符合上面的判断条件的。

所以,我们只需要建出圆方树,判断这个点是否在询问的两点间的路径上就行了。

  1. 对于删掉一条边的情况:

考虑我们建出来的广义圆方树是一种怎样的形态。它一定是圆方点交错的形式。换句话说,一条边若不在点双连通分量内,它就会变成一个方点,并连接其原来的两个点。

换句话说,我们把一条边转化成了一个点。于是我们就可以像上面处理点一样处理了。

实现

判断一个点是否在两点路径上,我们可以用树剖实现。具体来讲,在跳LCA的过程中判断被删点是否在起终点之间,我们用链首和深度判断即可。

由于题目查询边的给出方式约束,我们可以用 map 实现查询边是否在点双内。代码中,minmax 函数为 C++11 语法,其返回值为一个排好序后的 pair 。

整体时间复杂度为 \(O(n+q(\log n+\log m))\)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
inline int read(){
int w=0,x=0;char c=getchar();
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
return w?-x:x;
}
namespace star
{
const int maxn=2e5+10,maxm=5e5+10;
typedef pair<int,int> pii;
int n,m;
struct gragh{
int ecnt,head[maxn],to[maxm<<1],nxt[maxm<<1];
inline void addedge(int a,int b){
to[++ecnt]=b,nxt[ecnt]=head[a],head[a]=ecnt;
to[++ecnt]=a,nxt[ecnt]=head[b],head[b]=ecnt;
}
}G1,G2;
int tot,cnt,st[maxn],dfn[maxn],low[maxn];
map<pii,int> mp;
void tarjan(int x,int f){
dfn[x]=low[x]=++tot;
st[++st[0]]=x;
for(int i=G1.head[x];i;i=G1.nxt[i]){
int u=G1.to[i];
if(u==f)continue;
if(!dfn[u]){
tarjan(u,x);
low[x]=min(low[x],low[u]);
if(low[u]>=dfn[x]){
cnt++;
if(low[u]>dfn[x]) mp.insert(make_pair(minmax(u,x),cnt));
G2.addedge(cnt,x);
int now=-1;
while(now^u)
now=st[st[0]--],G2.addedge(now,cnt);
}
}else low[x]=min(low[x],dfn[u]);
}
}
int fa[maxn],dep[maxn],top[maxn],son[maxn],siz[maxn];
void dfs1(int x,int f){
fa[x]=f,dep[x]=dep[f]+1;siz[x]=1;
for(int i=G2.head[x];i;i=G2.nxt[i]){
int u=G2.to[i];
if(u==f)continue;
dfs1(u,x);
siz[x]+=siz[u];
if(siz[u]>siz[son[x]])son[x]=u;
}
}
void dfs2(int x,int topf){
top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(int i=G2.head[x];i;i=G2.nxt[i]){
int u=G2.to[i];
if(u==fa[x] or u==son[x]) continue;
dfs2(u,u);
}
}
inline bool LCA(int x,int y,int z){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
if(top[x]==top[z] and dep[z]<=dep[x]) return 1;
x=fa[top[x]];
}
if(dep[x]<dep[y])swap(x,y);
if(top[x]==top[z] and dep[z]>=dep[y] and dep[z]<=dep[x]) return 1;
return 0;
}
inline void work(){
n=cnt=read(),m=read();
for(int i=1;i<=m;i++) G1.addedge(read(),read());
tarjan(1,0);
dfs1(1,0);
dfs2(1,1);
int Q=read();
while(Q--)
if(read()==1){
int x=read(),y=read();
map<pii,int>::iterator it=mp.find(minmax(read(),read()));
if(it==mp.end()) puts("yes");
else puts(LCA(x,y,(*it).second)?"no":"yes");
}else{
int x=read(),y=read(),z=read();
puts(LCA(x,y,z)?"no":"yes");
}
}
}
signed main(){
star::work();
return 0;
}

P4334 [COI2007] Policija的更多相关文章

  1. [hdu P4334] Trouble

    [hdu P4334] Trouble Hassan is in trouble. His mathematics teacher has given him a very difficult pro ...

  2. 洛谷 P1823 [COI2007] Patrik 音乐会的等待

    洛谷 P1823 [COI2007] Patrik 音乐会的等待 洛谷传送门 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A ...

  3. 洛谷 P1823 [COI2007] Patrik 音乐会的等待 题解

    P1823 [COI2007] Patrik 音乐会的等待 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相 ...

  4. 洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找)

    洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1333275 这个题不是很 ...

  5. [COI2007] Sabor

    下面给出这道一脸不可做的题的鬼畜性质: 1)对于一个点来说,其归属状态是确定的:走不到.A党或B党 .(黑白格染色) 方便起见,将包含所有不可达的点的极小矩形向外扩展一圈,设为矩形M. 2)矩形M的最 ...

  6. P1823 [COI2007] Patrik 音乐会的等待 单调栈 洛谷luogu

    题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...

  7. 【洛谷】【单调栈】P4333 [COI2007] Patrik

    --接上一篇题解,[洛谷][单调栈]P1823音乐会的等待 关于题目大意在上一篇题解里已经说清楚了,这里不再多阐述 想看题目->戳这里 [算法分析:] 在对元素a进行判断时,如果它与栈顶元素相等 ...

  8. 洛谷P1823 [COI2007] Patrik 音乐会的等待

    https://www.luogu.org/problemnew/show/P1823 自己只会一个log的 设取的人的位置分别是l,r(l<r) 这个做法大概是考虑枚举r,设法对于每个r求出有 ...

  9. [COI2007] Patrik 音乐会的等待 (单调栈,模拟)

    题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...

随机推荐

  1. HDFS 05 - HDFS 常用的 Java API 操作

    目录 0 - 配置 Hadoop 环境(Windows系统) 1 - 导入 Maven 依赖 2 - 常用类介绍 3 - 常见 API 操作 3.1 获取文件系统(重要) 3.2 创建目录.写入文件 ...

  2. Java如何利用for循环在控制台输出正方形对角线图形

    1 /* 2 利用循环在控制台输出如下正方形对角线图形 3 * * * * * * * * * * * 4 * * * * 5 * * * * 6 * * * * 7 * * * * 8 * * * ...

  3. 五、自定义Zabbix监控项目

    要求: 沿用练习三,使用Zabbix实现自定义监控,实现以下目标:监控Linux服务器系统账户的数量. 方案: 需要使用Zabbix自定义key的方式实现自定义监控,参考如下操作步骤:1.创建自定义k ...

  4. 【dp】10-8题解 vacation

    vacations 原题codeforeces round 363 (Div2) c 题目描述 暑假到了, Pb 正在计划他的假期. Pb 准备假期去体育馆锻炼或看电影.但体育馆和电影院都有可能当天不 ...

  5. BLO

    BLO 内存限制:162 MiB 时间限制:1000 ms 标准输入输出     题目描述 Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ...

  6. windows 上 OpenSSH 服务 启用秘钥登录(微软真心逆天)

    windows 上 OpenSSH 服务 启用秘钥登录(微软真心逆天) windows 安装 OpenSSH 服务 最近需要在windows 服务器上部署自动发布程序,那么就需要用到 scp 和 ss ...

  7. 『无为则无心』Python基础 — 16、Python序列之字符串的下标和切片

    目录 1.序列的概念 2.字符串的下标说明 3.字符串的切片说明 1.序列的概念 序列sequence是Python中最基本的数据结构.指的是一块可存放多个值的连续内存空间,这些值按一定顺序排列,可通 ...

  8. POJ 1050 To the Max 枚举+dp

    大致题意: 求最大子矩阵和 分析: 一开始想复杂了,推出了一个状态方程:d[i][j]=max(d[i][j-1]+-,d[i-1][j]+-).写着写着发现上式省略的部分记录起来很麻烦. 后来发现n ...

  9. Vue 全局组件

    全局注册的组件可以在其他组件内直接使用,它在整个Vue实例中都是全局有效的. 非单文件组件中使用 Vue.component('student-list', { template: ` <div ...

  10. CRM系统选型时的参考哪些方面

    企业不论在制定营销策略或是在进行CRM系统选型时,首先都是要了解自身的需求.每一家企业的情况和需求都有很大差异,CRM系统的功能也都各有偏重.有些CRM偏重销售管理.有些注重于营销自动化.有些则侧重于 ...