题意

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

考虑分治询问序列,假设当前在\([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. python3解决url编码与解码

    对于url编码的转换,主要用urllib.parse包中的quote和unquote方法. quote进行解码,unquote进行编码. 代码实例: import urllib.parse u = & ...

  2. 如何解决android 通知栏不显示的问题

    android 8.0 以后的版本,在创建通知栏的时候,加了一个channelId的东西.要想在上述版本中显示通知,总共分两步 1.创建Channel if (Build.VERSION.SDK_IN ...

  3. angular路由事件

    Angular 4检测路由变化,可以使用router.events来监听: 支持的事件类型: NavigationStart:导航开始 NavigationEnd:导航结束 NavigationCan ...

  4. linux shell攻略学习笔记二

    1.Cat命令 这么多命令,常用的 Cat –n file  显示文件以及行数 Cat - echo 'Text through stdin' | cat - file.txt Text throug ...

  5. java之获取变量的类型

    java要获取变量的类型必须自己定义一个函数: public class Test{ public static void main(String[] args) { short a = 1; a + ...

  6. php 数组赋值

    结果: 结论:第一种方式的运行速度是第二种方式的二倍左右.

  7. electron应用生成exe程序并打包过程记录

    1.写好应用程序后,安装 electron-packager 在 package.json 文件中加入配置项目 "scripts": { "build": &q ...

  8. 【zibbix自定义监控】zabbix服务自定义监控mysql的状态信息

    由于mysql我安装在zabbix_server服务的主机上,所以下面操作在zabbix服务主机上进行,注意服务主机已经安装了监控服务 实现步骤: 1.修改 zabbix_agentd.conf,添加 ...

  9. jackson json转实体对象 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException

    Jackson反序列化错误:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field的解 ...

  10. vs未能正确加载CSharpPackage包,未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包

    VS2017打开项目时提示未能正确加载CSharpPackage包, 可以使用 devenv命令工具来解决,操作如下 打开vs2017开发人员命令提示符(请使用管理员身份运行),如图 敲入  deve ...