连通图

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. 四大IO抽象类

     四大IO抽象类   InputStream/OutputStream和Reader/writer类是所有IO流类的抽象父类,我们有必要简单了解一下这个四个抽象类的作用.然后,通过它们具体的子类熟悉相 ...

  2. 3,SQL语句及数据库优化

       1,统一SQL语句的写法 对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的. 所以封装成复用方法,用标准模板来控制. select*from dual select*Fr ...

  3. javac一次性编译多个包下的.java文件

    如题是我想要知道的,然后在网上搜了一下 下面是在某些帖子里看到别人说的只言片语 =========================================================== ...

  4. 阅读MDN文档之布局(四)

    Introducing positioning Static positioning Relative positioning Introducing top, bottom, left and ri ...

  5. XPivot 用户手册及版本更新公示

    此文仅介绍XPivot的通用功能,如有对项目中定制的高级功能感兴趣的可留言讨论 XPivot当前版本v2.2 [2015-04-20发布] v2.1 下载链接: http://pan.baidu.co ...

  6. tensorflow学习笔记(1)-基本语法和前向传播

    tensorflow学习笔记(1) (1)tf中的图 图中就是一个计算图,一个计算过程.                                       图中的constant是个常量 计 ...

  7. BZOJ 3925 ZJOI2015 地震后的幻想乡 状压dp+期望

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3925 题意概述: 给出一张N点M边的最小生成树,其中每条边的长度为[0,1]的实数,求最小 ...

  8. DP入门(2)——DAG上的动态规划

    有向无环图(DAG,Directed Acyclic Graph)上的动态规划是学习动态规划的基础.很多问题都可以转化为DAG上的最长路.最短路或路径计数问题. 一.DAG模型 [嵌套矩形问题] 问题 ...

  9. linux 下端口进程的查看

    1.netstat -tunlp : 会显示所有端口和所有对应的程序    /netstat -tln:也可显示被占用的端口 netstat -tln 1.1  netstat -tunlp |gre ...

  10. android扁平化ProgressBar--progressWheel

    ProgressWheel是git是一个开源项目,为开发者提供一个扁平化的ProgressBar,并可对其进行深度定制   1,将ProgressWheel的源码拷贝到项目中 public class ...