P4334 [COI2007] Policija
P4334 [COI2007] Policija
题意
一个无重边的无向图,每次询问删掉一条边或删掉一个点后两个点是否联通。
思路
连通性问题,我们可以考虑使用广义圆方树解决。
- 对于删掉一个点的情况:
我们先跑 tarjan 建出圆方树。如何判断两点在删去一个点后在树上的连通性?当且仅当被删去的点在两点间的路径上。根据圆方树的性质,如果被删点在一个点双连通分量中,它是符合上面的判断条件的。
所以,我们只需要建出圆方树,判断这个点是否在询问的两点间的路径上就行了。
- 对于删掉一条边的情况:
考虑我们建出来的广义圆方树是一种怎样的形态。它一定是圆方点交错的形式。换句话说,一条边若不在点双连通分量内,它就会变成一个方点,并连接其原来的两个点。
换句话说,我们把一条边转化成了一个点。于是我们就可以像上面处理点一样处理了。
实现
判断一个点是否在两点路径上,我们可以用树剖实现。具体来讲,在跳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的更多相关文章
- [hdu P4334] Trouble
[hdu P4334] Trouble Hassan is in trouble. His mathematics teacher has given him a very difficult pro ...
- 洛谷 P1823 [COI2007] Patrik 音乐会的等待
洛谷 P1823 [COI2007] Patrik 音乐会的等待 洛谷传送门 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A ...
- 洛谷 P1823 [COI2007] Patrik 音乐会的等待 题解
P1823 [COI2007] Patrik 音乐会的等待 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相 ...
- 洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找)
洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1333275 这个题不是很 ...
- [COI2007] Sabor
下面给出这道一脸不可做的题的鬼畜性质: 1)对于一个点来说,其归属状态是确定的:走不到.A党或B党 .(黑白格染色) 方便起见,将包含所有不可达的点的极小矩形向外扩展一圈,设为矩形M. 2)矩形M的最 ...
- P1823 [COI2007] Patrik 音乐会的等待 单调栈 洛谷luogu
题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...
- 【洛谷】【单调栈】P4333 [COI2007] Patrik
--接上一篇题解,[洛谷][单调栈]P1823音乐会的等待 关于题目大意在上一篇题解里已经说清楚了,这里不再多阐述 想看题目->戳这里 [算法分析:] 在对元素a进行判断时,如果它与栈顶元素相等 ...
- 洛谷P1823 [COI2007] Patrik 音乐会的等待
https://www.luogu.org/problemnew/show/P1823 自己只会一个log的 设取的人的位置分别是l,r(l<r) 这个做法大概是考虑枚举r,设法对于每个r求出有 ...
- [COI2007] Patrik 音乐会的等待 (单调栈,模拟)
题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的. ...
随机推荐
- 阅读源码很重要,以logback为例,分享一个小白都能学会的读源码方法
作为一个程序员,经常需要读一些开源项目的源码.同时呢,读源码对我们也有很多好处: 1.提升自己 阅读优秀的代码,第一可以提升我们自身的编码水平,第二可以开拓我们写代码的思路,第三还可能让我们拿到大厂 ...
- SpringCloud Alibaba实战(7:nacos注册中心管理微服务)
源码地址:https://gitee.com/fighter3/eshop-project.git 持续更新中-- 在上一节我们已经完成了Nacos Server的本地部署,这一节我们学习如何将Nac ...
- 技术实践:教你用Python搭建gRPC服务
摘要:gRPC是一个高性能.通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf序列化协议开发,且支持众多开发语言. 本文分享自华为云社区& ...
- 整合Spring Cloud Stream Binder与RabbitMQ进行消息发送与接收
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 前言 Spring Cloud Stream专门用于事件驱动的微服务系统,使用消息中间件来收发信息.使用Spring ...
- 配置中心之Nacos简介,使用及Go简单集成
简介 为什么需要配置中心 我们现在有一个项目, 使用Gin进行开发的, 配置文件我们知道是一个config.yaml的文件, 也知道这个配置文件在项目启动时会被加载到内存中使用; 考虑三种情况: ...
- 什么是WAF?
1.什么是Web Application Firewall(WAF)? WAF或Web Application Firewall通过过滤和监控Web应用程序与Internet之间的HTTP流量来帮助保 ...
- redis字典快速映射+hash釜底抽薪+渐进式rehash | redis为什么那么快
前言 相信你一定使用过新华字典吧!小时候不会读的字都是通过字典去查找的.在Redis中也存在相同功能叫做字典又称为符号表!是一种保存键值对的抽象数据结构 本篇仍然定位在[redis前传]系列中,因为本 ...
- flex中Button事件中的e.target
关于flex中的Button事件中的e.target. 今天想在事件中调用模块中的对象通过e.target获取单击的这个Button对象,但是可能是使用var btn:Button = e.targe ...
- Gym - 101128E Wooden Signs DP
题目大意: 一共n块木板,前两个数给出最底下木块的两个端点,后面n-1个数给出第i层的一个固定端点,问你木块的所有放置情况. 分析: 状态: d[i][j]表示第i个木块,第i-1块木板的未固定端点为 ...
- MySQL主从异常恢复
说明 MySQL主从出现不同步的情况时,或者要添加新的从库时,可以使用以下方法进行操作回复主从. 停止业务应用 停止所有连接到主从库上的应用,在恢复主从期间禁止任何增删改等操作,否则恢复失败 停止主从 ...