题意

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

考虑分治询问序列,假设当前在\([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. 201871010116-祁英红《面向对象程序设计(java)》第十四周学习总结

    博文正文开头格式:(2分) 项目 内容 <面向对象程序设计(java)> https://home.cnblogs.com/u/nwnu-daizh/ 这个作业的要求在哪里 https:/ ...

  2. python操作队列

    进行队列的操作,首先要引入queue这个库 一:设置队列(括号中是队列可容纳数据的多少,如果不设置,则可以一直增加) import queue q = queue.Queue(10) 二:添加/获取元 ...

  3. python直接赋值、浅拷贝、深拷贝的区别

    一:直接赋值 赋值,就是对象的引用,给对象起别名. i = 8j = iprint("值是:",i, "地址:",id(i))print("值是:&q ...

  4. 第05组 Alpha冲刺(2/4)

    第05组 Alpha冲刺(2/4) 队名:天码行空 组长博客连接 作业博客连接 团队燃尽图(共享): GitHub当日代码/文档签入记录展示(共享): 组员情况: 组员1:卢欢(组长) 过去两天完成了 ...

  5. 手摸手教你bootstrap定制

    老实说我一直不太喜欢使用bootstrap,bootstrap样式组件虽然丰富但实际开发使用到的不多:栅格系统虽然好用,满屏div也是看的头疼:所以当经理说要用bootstrap开发新项目的时候,我内 ...

  6. 四种PHP异步执行的常用方式

    本文为大家讲述了php异步调用方法,分享给大家供大家参考,具体内容如下 客户端与服务器端是通过HTTP协议进行连接通讯,客户端发起请求,服务器端接收到请求后执行处理,并返回处理结果. 有时服务器需要执 ...

  7. 【shell脚本】nginx启动脚本

    [root@localhost init.d]# cat nginx #!/bin/bash #nx Startup script for the Nginx HTTP Server # it ver ...

  8. HTML5新特性——自定义滑动条(input[type="range"])

    HTML 4.01 与 HTML5之间的差异 以下 input 的 type属性值是 HTML5 中新增的: color.date.datetime.datetime-local.month.week ...

  9. Day02stu

    ⦁ 环境搭建之接口测试工具Jmeter搭建 1) 什么是Jmeter? Jmeter是一个接口测试工具,基于Java开发,是是Apche公司使用Java平台开发的一款测试工具. 运行环境需要配置:JD ...

  10. java web工程的配置文件

    java web工程的配置文件 1.工程(源码依赖管理) 2.代码生成管理: 3.会话管理:servlet: 4.应用管理: 5.(分布式)资源管理:数据.数据库连接等. pom:源码管理工具 位置: ...