BZOJ 3237: [Ahoi2013]连通图
3237: [Ahoi2013]连通图
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 1161 Solved: 399
[Submit][Status][Discuss]
Description
.jpg)
Input
.jpg)
Output
.jpg)
Sample Input
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
Source
很有意思的一道题。乍一看就是LCT,后来听说可以CDQ水过,一想确实哎,写写就1A了。
对于一张图的连通性,我们可以用并查集维护,简单方便,可是不支持删边操作(这里指的是随机的删边)。但发现可以通过记录father数组的更改,得到一个回溯栈,方便地进行顺序删边。
利用CDQ分治的想法,在一个solve(l,r)时,考虑把(mid,r]内的边补回到图中,维护并查集并记录改变(用来回溯),然后递归solve(l,mid),最后回溯;再把[l,mid]的边补回,递归右侧,回溯。这样到底层solve(l,r),即l==r时,并查集维护的刚好不包含当前这组询问中的边,此时记录下答案即可。
#include <bits/stdc++.h>
inline int getC(void) {
static const int siz = ;
static char buf[siz];
static char *hd = buf + siz;
static char *tl = buf + siz;
if (hd == tl)
fread(hd = buf, , siz, stdin);
return int(*hd++);
}
inline int getI(void) {
register int ret = ;
register int neg = false;
register int bit = getC();
for (; bit < ; bit = getC())
if (bit == '-')neg ^= true;
for (; bit > ; bit = getC())
ret = ret * + bit - '';
return neg ? -ret : ret;
}
const int maxn = ;
int n, m, p;
struct edge {
int x, y;
}e[maxn];
struct query {
int k, s[];
bool connect;
}q[maxn];
int fa[maxn];
int sz[maxn];
int cnt[maxn];
inline int find(int u) {
while (fa[u] != u)
u = fa[u];
return u;
}
int stk[maxn], tot;
void solve(int l, int r) {
if (l == r) {
q[l].connect = sz[find()] == n;
return;
}
int mid = (l + r) >> , top = tot;
for (int i = l; i <= mid; ++i)
for (int j = ; j <= q[i].k; ++j)
if (--cnt[q[i].s[j]] == ) {
int x = find(e[q[i].s[j]].x);
int y = find(e[q[i].s[j]].y);
if (x != y) {
if (sz[x] < sz[y])
fa[x] = y, sz[y] += sz[x], stk[++tot] = x;
else
fa[y] = x, sz[x] += sz[y], stk[++tot] = y;
}
}
solve(mid + , r);
while (tot > top) {
int t = stk[tot--];
sz[fa[t]] -= sz[t];
fa[t] = t;
}
for (int i = l; i <= mid; ++i)
for (int j = ; j <= q[i].k; ++j)
++cnt[q[i].s[j]];
for (int i = mid + ; i <= r; ++i)
for (int j = ; j <= q[i].k; ++j)
if (--cnt[q[i].s[j]] == ) {
int x = find(e[q[i].s[j]].x);
int y = find(e[q[i].s[j]].y);
if (x != y) {
if (sz[x] < sz[y])
fa[x] = y, sz[y] += sz[x], stk[++tot] = x;
else
fa[y] = x, sz[x] += sz[y], stk[++tot] = y;
}
}
solve(l, mid);
while (tot > top) {
int t = stk[tot--];
sz[fa[t]] -= sz[t];
fa[t] = t;
}
for (int i = mid + ; i <= r; ++i)
for (int j = ; j <= q[i].k; ++j)
++cnt[q[i].s[j]];
}
signed main(void) {
n = getI();
m = getI();
for (int i = ; i <= n; ++i)
fa[i] = i, sz[i] = ;
for (int i = ; i <= m; ++i)
e[i].x = getI(),
e[i].y = getI();
p = getI();
for (int i = ; i <= p; ++i) {
q[i].k = getI();
for (int j = ; j <= q[i].k; ++j)
++cnt[q[i].s[j] = getI()];
}
for (int i = ; i <= m; ++i)
if (!cnt[i]) {
int x = find(e[i].x);
int y = find(e[i].y);
if (x != y) {
if (sz[x] < sz[y])
fa[x] = y, sz[y] += sz[x];
else
fa[y] = x, sz[x] += sz[y];
}
}
solve(, p);
for (int i = ; i <= p; ++i)
puts(q[i].connect ? "Connected" : "Disconnected");
}
@Author: YouSiki
BZOJ 3237: [Ahoi2013]连通图的更多相关文章
- BZOJ 3237([Ahoi2013]连通图-cdq图重构-连通性缩点)
3237: [Ahoi2013]连通图 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 106 Solved: 31 [ Submit][ St ...
- 3237: [Ahoi2013]连通图 线段树分治
题解: cf765f cf671e bzoj4184 bzoj4552 线段树分治裸题 还是介绍一下线段树分治 这个东西其实挺简单但也挺有用的 可以把删除+插入操作变成只有插入(倒着就是删除) 像这一 ...
- [BZOJ3237][AHOI2013]连通图(分治并查集)
3237: [Ahoi2013]连通图 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1736 Solved: 655[Submit][Status ...
- BZOJ 3233: [Ahoi2013]找硬币
BZOJ 3233: [Ahoi2013]找硬币 标签(空格分隔): OI-BZOJ OI-DP Time Limit: 10 Sec Memory Limit: 64 MB Description ...
- BZOJ 3235: [Ahoi2013]好方的蛇
BZOJ 3235: [Ahoi2013]好方的蛇 标签(空格分隔): OI-BZOJ OI-DP OI-容斥原理 Time Limit: 10 Sec Memory Limit: 64 MB Des ...
- 线段树分治初步学习&洛谷P5227[AHOI2013]连通图
线段树分治 其实思想说起来是比较简单的,我们把这个题里的所有操作(比如连边删边查询balabala)全部拍到一棵线段树上,然后对着整棵树dfs一下求解答案,顺便把操作做一下,回溯的时候撤销一下即可.虽 ...
- bzoj 3237 连通图 - 并查集 - 线段树
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 Disconne ...
- 【bzoj3237】 Ahoi2013—连通图
http://www.lydsy.com/JudgeOnline/problem.php?id=3237 (题目链接) 题意 给出一个无向图,$Q$组询问,每次询问将原图断掉$C$条边后是否还连通. ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
随机推荐
- Linux发邮件之mail命令
一.mail命令 1.配置 vim /etc/mail.rc 文件尾增加以下内容 set from=1968089885@qq.com smtp="smtp.qq.com" set ...
- FFmpeg学习5:多线程播放视音频
在前面的学习中,视频和音频的播放是分开进行的.这主要是为了学习的方便,经过一段时间的学习,对FFmpeg的也有了一定的了解,本文就介绍了 如何使用多线程同时播放音频和视频(未实现同步),并对前面的学习 ...
- meta标签
参考:http://www.jb51.net/web/158860.html META标签分两大部分:HTTP标题信息(HTTP-EQUIV)和页面描述信息(NAME). 一.HTTP标题信息(HTT ...
- go语言赋值
使用赋值语句可以更新一个变量的值,最简单的赋值语句是将要被赋值的变量放在=的左边,新值的表达式放在=的右边. x = // 命名变量的赋值 *p = true // 通过指针间接赋值 person.n ...
- 如果你也会C#,那不妨了解下F#(4):了解函数及常用函数
函数式编程其实就是按照数学上的函数运算思想来实现计算机上的运算.虽然我们不需要深入了解数学函数的知识,但应该清楚函数式编程的基础是来自于数学. 例如数学函数\(f(x) = x^2+x\),并没有指定 ...
- 了解java注解
类似于下面这样的就是注解 注解可以在类上,成员变量上,方法上等 假如有2个注解是这样的:(其中的Author和Date) 那么这2个注解的定义就是这样的: Author注解: Date注解: 可以看到 ...
- El表达式的关系运算符
El表达式的关系运算符: == 对应 eq != 对应 ne > 对应 gt < 对应 It
- android Broadcast介绍
在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制.而BroadcastReceiver是对发送出来的Broadcast进行过滤接受并响应的一类组件.发送Broadca ...
- Android Studio使用时源码到处报红色警告,运行时又没错
转载地址:http://www.07net01.com/program/2016/04/1452749.html [摘要:正在AS上开辟时,碰到那个题目,翻开全部的Java源文件,右边一起标赤色,找没 ...
- 将Oracle数据库中的数据写入Excel
将Oracle数据库中的数据写入Excel 1.准备工作 Oracle数据库"TBYZB_FIELD_PRESSURE"表中数据如图: Excel模板(201512.xls): 2 ...