LOJ121 「离线可过」动态图连通性
思路
动态图连通性的板子,可惜我不会在线算法
离线可以使用线段树分治,每个边按照存在的时间插入线段树的对应节点中,最后再dfs一下求出解即可,注意并查集按秩合并可以支持撤销操作
由于大量使用STL跑的很慢的代码
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <set>
#include <map>
const int MAXN = 5101;
const int MAXM = 500100;
using namespace std;
int n,timex=0,m,ans[MAXM],cnt;
struct Udsu{
int h[MAXN],fa[MAXN];
stack<int> mer,height;
int find(int x){
if(fa[x]==x)
return x;
else
return find(fa[x]);
}
bool query(int x,int y){
return find(x)==find(y);
}
void merge(int x,int y){
x=find(x);
y=find(y);
if(h[x]<=h[y]){
mer.push(x);
fa[x]=y;
if(h[x]==h[y]){
h[y]++;
height.push(1);
}
else
height.push(0);
}
else{
mer.push(y);
fa[y]=x;
height.push(0);
}
}
void undo(void){
int x=mer.top();
mer.pop();
int val=height.top();
height.pop();
h[fa[x]]-=val;
fa[x]=x;
}
void init(void){
for(int i=1;i<=n;i++)
h[i]=1,fa[i]=i;
}
}DSU;
struct edge{
int u,v;
bool operator < (const edge &b) const{
return u<b.u||(u==b.u&&v<b.v);
}
};
struct Node{
int le,u,v;//-1 add else query
bool operator < (const Node &b) const{
return le<b.le;
}
};
map<edge,int> M;
vector<Node> seg[MAXM<<2];
void add(int l,int r,int L,int R,int o,int le,int u,int v){
// printf("add l=%d r=%d L=%d R=%d o=%d\n",l,r,L,R,o);
// Sleep(700);
if(L<=l&&r<=R){
seg[o].push_back((Node){le,u,v});
return;
}
int mid=(l+r)>>1;
if(L<=mid)
add(l,mid,L,R,o<<1,le,u,v);
if(R>mid)
add(mid+1,r,L,R,o<<1|1,le,u,v);
}
void dfs(int l,int r,int o){
// printf("l=%d r=%d o=%d\n",l,r,o);
sort(seg[o].begin(),seg[o].end());
for(int i=0;i<seg[o].size();i++){
if(seg[o][i].le==-1){
DSU.merge(seg[o][i].u,seg[o][i].v);
// printf("link %d %d\n",seg[o][i].u,seg[o][i].v);
}
else{
ans[seg[o][i].le]=DSU.query(seg[o][i].u,seg[o][i].v);
// printf("query %d %d\n",seg[o][i].u,seg[o][i].v);
}
}
if(l!=r){
int mid=(l+r)>>1;
dfs(l,mid,o<<1);
dfs(mid+1,r,o<<1|1);
}
for(int i=0;i<seg[o].size();i++)
if(seg[o][i].le==-1){
// printf("undo\n");
DSU.undo();
}
}
int main(){
scanf("%d %d",&n,&m);
DSU.init();
for(int i=1;i<=m;i++){
++timex;
int opt,u,v;
scanf("%d %d %d",&opt,&u,&v);
if(u>v)
swap(u,v);
if(opt==0){
M[((edge){u,v})]=timex;
}
if(opt==1){
// printf("addtime=%d endtime=%d\n",M[((edge){u,v})],timex);
add(1,m+1,M[((edge){u,v})],timex,1,-1,u,v);
M.erase((edge){u,v});
}
if(opt==2){
add(1,m+1,timex,timex,1,++cnt,u,v);
}
}
++timex;
for(map<edge,int>::iterator it=M.begin();it!=M.end();it++){
add(1,m+1,(*it).second,m+1,1,-1,(*it).first.u,(*it).first.v);
}
dfs(1,m+1,1);
for(int i=1;i<=cnt;i++){
printf("%s\n",(ans[i])?"Y":"N");
}
return 0;
}
LOJ121 「离线可过」动态图连通性的更多相关文章
- 【LOJ121】「离线可过」动态图连通性
[LOJ121]「离线可过」动态图连通性 题面 LOJ 题解 线段树分治的经典应用 可以发现每个边出现的时间是一个区间 而我们每个询问是一个点 所以我们将所有边的区间打到一颗线段树上面去 询问每个叶子 ...
- LOJ 121 「离线可过」动态图连通性——LCT维护删除时间最大生成树 / 线段树分治
题目:https://loj.ac/problem/121 离线,LCT维护删除时间最大生成树即可.注意没有被删的边的删除时间是 m+1 . 回收删掉的边的节点的话,空间就可以只开 n*2 了. #i ...
- LOJ#121. 「离线可过」动态图连通性(线段树分治)
题意 板子题,题意很清楚吧.. Sol 很显然可以直接上LCT.. 但是这题允许离线,于是就有了一个非常巧妙的离线的做法,好像叫什么线段树分治?? 此题中每条边出现的位置都可以看做是一段区间. 我们用 ...
- LOJ #121. 「离线可过」动态图连通性 LCT维护最大生成树
这个还是比较好理解的. 你考虑如果所有边构成一棵树的话直接用 LCT 模拟一波操作就行. 但是可能会出现环,于是我们就将插入/删除操作按照时间排序,然后依次进行. 那么,我们就要对我们维护的生成树改变 ...
- 【LOJ】#121. 「离线可过」动态图连通性
题解 和BZOJ4025挺像的 就是维护边权是时间的最大生成树 删边直接删 两点未联通时直接相连,两点联通则找两点间边权小的一条边删除即可 代码 #include <bits/stdc++.h& ...
- loj#121.「离线可过」动态图连通性
题面 话说#122怎么做啊 题解 我的\(\mathrm{LCT}\)水平极差,连最小生成树都快忘了,赶紧复习一下 做法和这篇是一样的 这道题还可以练习线段树分治 还可以练习ETT 果然是道吼题 代码 ...
- 「LOJ 121」「离线可过」动态图连通性「按时间分治 」「并查集」
题意 你要维护一张\(n\)个点的无向简单图.你被要求执行\(m\)条操作,加入删除一条边及查询两个点是否连通. 0:加入一条边.保证它不存在. 1:删除一条边.保证它存在. 2:查询两个点是否联通. ...
- LOJ121 【离线可过】动态图连通性
题目链接:戳我 [线段树分治版本代码] 这里面的线段树是时间线段树,每一个节点都要开一个vector,记录当前时间区间中存在的边的标号qwq #include<iostream> #inc ...
- [LOJ#121]动态图连通性
[LOJ#121]动态图连通性 试题描述 这是一道模板题. 你要维护一张无向简单图.你被要求加入删除一条边及查询两个点是否连通. 0:加入一条边.保证它不存在. 1:删除一条边.保证它存在. 2:查询 ...
随机推荐
- STL之Deque容器
1.Deque容器 1)deque是“double-ended queue”的缩写,和vector一样都是STL的容器,deque是双端数组,而vector是单端的. 2)deque在接口上和vect ...
- 在lua中从一个字符串中移除空间源码
/* trim.c - based on http://lua-users.org/lists/lua-l/2009-12/msg00951.html from Sean Conner */ #inc ...
- tr字符串的梗
工作问题总结 声明:应用程序代码为前人所写,仅仅只是维护代码,暂且不论代码风格瑕疵. 结论: 使用tr“包”起来的字符串,可能会被翻译为不同的语言,此时,应用程序在不同语言环境下可能会表现BUG. 1 ...
- flask模板应用-加载静态文件:添加Favicon,使用CSS框架,使用宏加载静态资源
加载静态文件 一个Web项目不仅需要HTML模板,还需要许多静态文件,比如CSS.JavaScript文件.图片和声音声.在flask程序中,默认需要将静态文件存储在与主脚本(包含程序实例的脚本)同级 ...
- EasyUI添加进度条
EasyUI添加进度条 添加进度条重点只有一个,如何合理安排进度刷新与异步调用逻辑,假如我们在javascript代码中通过ajax或者第三方框架dwr等对远程服务进行异步调用,实现进度条就需要做到以 ...
- 转:【专题四】自定义Web浏览器
前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发出请求的正是本专题要介绍的Web浏览器,本专题通过简单自定义一个Web浏览器来简单介绍浏览器的工作原理,以及帮助一些初学者揭开浏览器这 ...
- Codeforce 814A - An abandoned sentiment from past (贪心)
A few years ago, Hitagi encountered a giant crab, who stole the whole of her body weight. Ever since ...
- Linux下MySQL远程链接配置
配置步骤: 1).首先进入数据库,使用系统数据库mysql mysql -u root -p mysql 2).接着对系统数据库的root账户设置远程访问的密码,与本地的root访问密码并不冲突 gr ...
- ajax实现图片上传
1.创建formData表单,模拟表单传递数据(formData有兼容性问题) var formData = new FormData();2.获取到相应的元素 var jobName = $(&qu ...
- 怎样从外网访问内网Node.js?
本地安装了一个Node.js,只能在局域网内访问,怎样从外网也能访问到本地的Node.js呢?本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Node.js 默认安装的Node.js端口 ...