连通图

Time Limit: 20 Sec  Memory Limit: 512 MB
[Submit][Status][Discuss]

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

  Connected
  Disconnected
  Connected

HINT

  N<=100000 M<=200000 K<=100000

Main idea

  给定一张无向联通图,询问删除掉若干条边后图是否联通,多次询问。

Solution

  首先我们看到删边判联通,第一反应想到了LCT,由于图不是一棵树,无法用LCT实现,那么我们否决掉了动态维护的方法。
  根据可以离线询问这一特征来思考如何操作,发现k(询问数)<=100000,显然是log级别的做法,结合可离线的特征,这时候只剩下了对于所有询问一起进行操作的方法 ,现在我们得出了算法:CDQ分治。
  发现直接删边操作较为困难,我们逆向思维,考虑如何在一个空的图上加边
  先考虑只有两个询问的情况,假定我们的询问删边集合为A,B,那么显然想到了先把不在A中并且不在B中边加入(这时称其为状态一),然后分开处理,先加入不在A中但是在B中的边,判下是否联通就得到了A中的答案,然后回到状态一,加入不在B中在A中的边,判断一下得到了B的答案
  然后基于这样的整个思路,我们考虑如何将两个集合拓展到多个集合
  立马想到了分治,对于所有集合分治使其类同于A,B两种“大集合”,然后继续分治,最后必然可以归于仅有两个小集合的情况,然后向上回溯即可。加边用并查集加入即可。
  我们来整理一下CDQ分治的思路:
    1、加入不在左区间但在右区间的边;
    2、对于左区间继续分治;
    3、回到上一层的状态(在分治的时候记录并查集中改变了的父子关系,暴力修改回去即可)
    4、加入不在右区间但在左区间的边;
    5、对于右区间继续分治;
    ……
  最后判断是否联通的时候又发现一开始的整张图是处于连通状态的,所以我们只要判断删掉的边的端点是否连通即可。

Code

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std; const int ONE=; int n,m,Bian;
int fat[ONE],cnt;
int PD[ONE];
int Ans[ONE]; struct power
{
int x,y;
}a[ONE*],q[ONE*]; struct point
{
int c;
int b[];
}quey[ONE]; int get()
{
int res,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int Find(int x)
{
if(x!=fat[x])
{
q[++cnt].x=x; q[cnt].y=fat[x];
fat[x]=Find(fat[x]);
}
return fat[x];
} void Un(int x,int y)
{
int f1=Find(x);
int f2=Find(y);
if(f1!=f2)
{
q[++cnt].x=f2; q[cnt].y=fat[f2];
fat[f2]=f1;
}
} int Get_pd(int l)
{
int pd=;
for(int i=;i<=quey[l].c;i++)
{
int j=quey[l].b[i];
if(Find(a[j].x) != Find(a[j].y))
{
pd=;
break;
}
}
return pd;
} void Mark(int l,int r,int t)
{
for(int i=l;i<=r;i++)
{
for(int j=;j<=quey[i].c;j++)
PD[quey[i].b[j]]=t;
}
} void Add(int l,int r)
{
for(int i=l;i<=r;i++)
{
for(int j=;j<=quey[i].c;j++)
{
int num=quey[i].b[j];
if(PD[num]) continue;
Un(a[num].x,a[num].y);
}
}
} void Back(int Now_cnt)
{
for(;cnt>Now_cnt;cnt--)
fat[q[cnt].x]=q[cnt].y;
} void CDQ(int l,int r)
{
if(l==r)
{
Ans[l]=Get_pd(l);
return;
} int Now_cnt=cnt;
int mid=(l+r)/;
Mark(l,mid,); Add(mid+,r); Mark(l,mid,);
CDQ(l,mid); Back(Now_cnt);
Mark(mid+,r,); Add(l,mid); Mark(mid+,r,);
CDQ(mid+,r);
} int main()
{
n=get(); Bian=get();
for(int i=;i<=n;i++) fat[i]=i;
for(int i=;i<=Bian;i++)
{
a[i].x=get(); a[i].y=get();
} m=get();
for(int i=;i<=m;i++)
{
quey[i].c=get();
for(int j=;j<=quey[i].c;j++)
quey[i].b[j]=get();
} Mark(,m,);
for(int i=;i<=Bian;i++)
{
if(PD[i]) continue;
Un(a[i].x,a[i].y);
}
Mark(,m,); cnt=; CDQ(,m); for(int i=;i<=m;i++)
{
if(Ans[i]) printf("Connected");
else printf("Disconnected");
printf("\n");
}
}

【BZOJ3237】【AHOI2013】连通图 [CDQ分治]的更多相关文章

  1. 2018.10.01 bzoj3237: [Ahoi2013]连通图(cdq分治+并查集)

    传送门 cdq分治好题. 对于一条边,如果加上它刚好连通的话,那么删掉它会有两个大集合A,B.于是我们先将B中禁用的边连上,把A中禁用的边禁用,再递归处理A:然后把A中禁用的边连上,把B中禁用的边禁用 ...

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

    3237: [Ahoi2013]连通图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1736  Solved: 655[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]连通图

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

  5. 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 ...

  6. BZOJ3237 AHOI2013连通图(线段树分治+并查集)

    把查询看做是在一条时间轴上.那么每条边都有几段存在时间.于是线段树分治就好了. 然而在bzoj上t掉了,不知道是常数大了还是写挂了. 以及brk不知道是啥做数组名过不了编译. #include< ...

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

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

  8. 【BZOJ3456】轩辕朗的城市规划 无向连通图计数 CDQ分治 FFT 多项式求逆 多项式ln

    题解 分治FFT 设\(f_i\)为\(i\)个点组成的无向图个数,\(g_i\)为\(i\)个点组成的无向连通图个数 经过简单的推导(枚举\(1\)所在的连通块大小),有: \[ f_i=2^{\f ...

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

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

随机推荐

  1. guacamole实现虚拟键盘

    要做的事情比较简单,就是先实例化一个虚拟键盘,然后监听事件即可. js代码 //虚拟键盘数据 var a = {"language":"en_US"," ...

  2. Flexbox布局模式的理解

    个人博客地址:  雨中的鱼-前端知识分享   http://www.showhtml5.cc    分享干货,有兴趣的人可以一起来分享前端知识  加Q群:440279380   Flexbox,一种C ...

  3. 【连载】Maven系列(三) 进阶

    相关文章: 1.<用起来超爽的Maven——入门篇> 2.<用起来超爽的Maven——进阶篇> 一.Maven坐标: Maven世界拥有大量需要构建jar文件,我们需要找一个用 ...

  4. ionic 向路由中的templateUrl(模板页)传值

    .state('product', { url: '/product/:id', templateUrl: function ($routeParams) { return '/Product/Ind ...

  5. 简单工具 & 杂技

    图片压缩: 腾讯智图(http://zhitu.isux.us/) 手机的所有尺寸大小规范: http://screensiz.es/phone 需求: 移动端宽高一致的盒子(因为移动端屏幕宽度不一样 ...

  6. 序列化反序列化--Xstream的使用

    之前讲了fastjson的使用--将JavaBean与json对象之间互相转换. 该篇文章,教大家使用Xstream来实现XMl与JavaBean的转换. 第一步: 通过maven引入XStream的 ...

  7. 第二篇 Python初识别及变量名定义规范

    第一个Python程序 可以打开notepad或者其他文本编辑器,输入:print("Hello Python!"),将文件保存到任意盘符下,后缀名是  .py 两种python程 ...

  8. zabbix 2.2 调小监控值

    zabbix_agent默认disk下小于0%告警 调小到5% 组态 > 模板 选择需要的模板的触发器 例如 Template OS Windows 选择触发器 - 探索规则 - 触发器类型  ...

  9. Python图像全屏显示

    需要在嵌入式设备上全屏显示图像,使用pil显示图像时,只能通过系统的图像浏览器显示.所以使用Python自带的tkinter import Tkinter as tk   这句在Python3中已经改 ...

  10. uva 11526 H(n) (数论)

    转载自 http://blog.csdn.net/synapse7/article/details/12873437 这道题我自己做的时候没有想到好的优化方法,提交的时候借鉴这篇文章的内容,转载如下: ...