题意

虽然没用线段树,但是仍然是线段树分治的思想。

考虑分治询问序列,假设当前在\([l,r]\),我们将\([1,l-1]\)和\([r+1,Q]\)的与\([l,r]\)内不重复的边都连上了。

先将\([mid+1,r]\)中与\([l,mid]\)不重复的边都连上,之后递归\([l,mid]\),再将之前的操作撤销,将\([l,mid+1]\)中与\([mid+1,r]\)不重复的边都连上,之后递归\([mid+1,r]\)。

发现当低递归到\([l,l]\)时,整个并查集正好是第\(l\)组询问的图的状态。

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int maxm=2*1e5+10;
const int maxQ=1e5+10;
int n,m,Q,top;
int fa[maxn],size[maxn];
bool ans[maxn],check[maxm];
struct Edge{int u,v;}E[maxm];
struct node{int x,y,sizey;}sta[maxQ];
vector<int>edge[maxQ];
inline int read()
{
char c=getchar();int res=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
return res*f;
}
int find(int x){return fa[x]==x?x:find(fa[x]);}
inline void merge(int u,int v,bool op)
{
int x=find(u),y=find(v);
if(x==y)return;
if(size[x]>size[y])swap(x,y);
if(op)sta[++top]=(node){x,y,size[y]};
fa[x]=y;size[y]+=size[x];
}
inline void cut(int id)
{
int x=sta[id].x,y=sta[id].y;
fa[x]=x;size[y]=sta[id].sizey;
}
void solve(int l,int r)
{
if(l==r){ans[l]=(size[find(1)]==n);return;}
int now=top,mid=(l+r)>>1;
for(int i=mid+1;i<=r;i++)
for(unsigned int j=0;j<edge[i].size();j++)
check[edge[i][j]]=1;
for(int i=l;i<=mid;i++)
for(unsigned int j=0;j<edge[i].size();j++)
check[edge[i][j]]=0;
for(int i=mid+1;i<=r;i++)
for(unsigned int j=0;j<edge[i].size();j++)
if(check[edge[i][j]])merge(E[edge[i][j]].u,E[edge[i][j]].v,1);
solve(l,mid);
while(top>now)cut(top),top--;
for(int i=l;i<=mid;i++)
for(unsigned int j=0;j<edge[i].size();j++)
check[edge[i][j]]=1;
for(int i=mid+1;i<=r;i++)
for(unsigned int j=0;j<edge[i].size();j++)
check[edge[i][j]]=0;
for(int i=l;i<=mid;i++)
for(unsigned int j=0;j<edge[i].size();j++)
if(check[edge[i][j]])merge(E[edge[i][j]].u,E[edge[i][j]].v,1);
solve(mid+1,r);
while(top>now)cut(top),top--;
for(int i=l;i<=mid;i++)
for(unsigned int j=0;j<edge[i].size();j++)
check[edge[i][j]]=0;
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)fa[i]=i,size[i]=1;
for(int i=1;i<=m;i++)E[i].u=read(),E[i].v=read();
Q=read();
for(int i=1;i<=Q;i++)
{
int k=read(),id;
while(k--)id=read(),edge[i].push_back(id);
}
for(int i=1;i<=n;i++)fa[i]=i,size[i]=1;
for(int i=1;i<=Q;i++)
for(unsigned int j=0;j<edge[i].size();j++)
check[edge[i][j]]=1;
for(int i=1;i<=m;i++)if(!check[i])merge(E[i].u,E[i].v,0);
solve(1,Q);
for(int i=1;i<=Q;i++)puts(ans[i]?"Connected":"Disconnected");
return 0;
}

luoguP5227 [AHOI2013]连通图的更多相关文章

  1. luoguP5227 [AHOI2013]连通图(线性基做法)

    题意 神仙哈希做法. 随便找个生成树,给每个非树边赋一个值,树边的值为所有覆盖它的边的值得异或和. 删去边集使得图不联通当且即当边集存在一个子集异或和为0,可以用线性基. 证明的话好像画个图挺显然的 ...

  2. BZOJ 3237: [Ahoi2013]连通图

    3237: [Ahoi2013]连通图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1161  Solved: 399[Submit][Status ...

  3. BZOJ 3237([Ahoi2013]连通图-cdq图重构-连通性缩点)

    3237: [Ahoi2013]连通图 Time Limit: 20 Sec   Memory Limit: 512 MB Submit: 106   Solved: 31 [ Submit][ St ...

  4. [BZOJ3237][AHOI2013]连通图(分治并查集)

    3237: [Ahoi2013]连通图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1736  Solved: 655[Submit][Status ...

  5. 线段树分治初步学习&洛谷P5227[AHOI2013]连通图

    线段树分治 其实思想说起来是比较简单的,我们把这个题里的所有操作(比如连边删边查询balabala)全部拍到一棵线段树上,然后对着整棵树dfs一下求解答案,顺便把操作做一下,回溯的时候撤销一下即可.虽 ...

  6. 【线段树分治】【P5227】 [AHOI2013]连通图

    Description 给定一个无向连通图和若干个小集合,每个小集合包含一些边,对于每个集合,你需要确定将集合中的边删掉后改图是否保持联通.集合间的询问相互独立 定义一个图为联通的当且仅当对于任意的两 ...

  7. bzoj3569 DZY Loves Chinese II & bzoj3237 [AHOI2013] 连通图

    给一个无向连通图,多次询问,每次询问给 k 条边,问删除这 k 条边后图的连通性,对于 bzoj3237 可以离线,对于 bzoj3569 强制在线 $n,m,q \leq 500000,k \leq ...

  8. BZOJ3237: [Ahoi2013]连通图

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3237 cdq分治+缩点. 可以每次处理的时候把除l~r之外的边的端点都连起来.然后去跑cdq分 ...

  9. BZOJ3237:[AHOI2013]连通图(线段树分治,并查集)

    Description Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connec ...

随机推荐

  1. 算法问题实战策略 GALLERY

    地址 https://algospot.com/judge/problem/read/GALLERY 分析 如图 显然是需要在 0 1 2三个点进行监控即可.(0 2 3 也可) 根据题意,不存在回路 ...

  2. antd配置config-overrides.js文件

    下载antd 包 npm install antd 下载依赖包(定义组件按需求打包) npm install react-app-rewired customize-cra babel-plugin- ...

  3. angular6 升级到 angular7+ 最新Ng-zorro

    angular7 出来有一段时间了,然后我们项目一直用的是angular6, 看到一直再用的Ng-Zorro 更新版本了,然后就觉得把目前的项目也升级一下把. 目前我本地cli版本是6.0.8我要把他 ...

  4. Linux 学习记录一(安装、基本文件操作).

    Linux 名字的由来,是当时作者将初版的 Linux 发布在网上,供别人下载完善,而那个核心文件夹就叫 Linux,就这么叫着了.而为什么 Linux 的吉祥物是一只企鹅呢?是因为当时大家要发行稳定 ...

  5. django--DateTimeField字段orm操作

    django中的models.py是我们用来创建数据库里需要的表的,规定表中各个字段的类型,选择合适的字段类型尤为重要,常用的字段类型有:CharField.choice.IntegerField.T ...

  6. 我用python训练了一个拳皇模型,从此在各地游戏厅再也没输过!

    ​ 从世界瞩目的围棋游戏 AlphaGo ​ ​ ​ 突然袭来的回忆杀~ 今天为大家介绍一个在街机游戏<街头霸王 3>中进行模拟来训练改进强化学习算法的工具包.不仅在 MAME 游戏模拟器 ...

  7. 创建workbook及相关操作

    通过openpyxl模块创建workbook时,无需本地事先创建好excel,它会直接创建一个新的excel文件 创建workbook时,会至少包含一个worksheet 注意:openpyxl模块只 ...

  8. 转载-ThreadPoolExecutor里面4种拒绝策略(详细)

    原文链接:https://blog.csdn.net/wjs19930820/article/details/79849050 1 /** * 定义异步任务执行线程池 */ @Configuratio ...

  9. JeeSite | 保存信息修改记录

    需求点 在很多场景中信息是不能轻易被修改的,修改时要么需要具备权限,要么需要审批,但是无论是哪种方式,修改前后的数据都是需要留有“案底”的,也就是说关键的信息被修改后是有修改记录的,一般修改记录会记录 ...

  10. rpmbuild打包

    安装: yum  install -y rpm-build 目录介绍: 默认目录在  /root/rpmbuild BUILD :你要打包的文件将会在这里编译(编译rpm包的临时目录) BUILDRO ...