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 ...
随机推荐
- spring整合mybatis使用<context:property-placeholder>时的坑
背景 最近项目要上线,需要开发一个数据迁移程序.程序的主要功能就是将一个数据库里的数据,查询出来经过一系列处理后导入另一个数据库.考虑到开发的方便快捷.自然想到用spring和mybatis整合一下. ...
- Java正则速成秘籍(三)之见招拆招篇
导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...
- java netty socket库和自定义C#socket库利用protobuf进行通信完整实例
之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...
- c#面向对象基础技能——学习笔记(五)委托技术在开发中的应用
委托 delegate 1.是一种全新的面向对象语言的特性: 2.开发事件驱动程序变得非常简单: 3.简化多线程难度. 理解委托:可以理解成一个方法的指针.(接收的变量是方法) 步骤: 1.声明委托, ...
- Entity Framework 教程——EF体系结构
EF体系结构 下图是一张EF体系结构的全景图,让我们单独了解各个组件的用处. EDM (Entity Data Model): EDM由3个主要部分组成,概念模块(Conceptual Model), ...
- 【C#】组件发布:MessageTip,轻快型消息提示窗
-------------201610212046更新------------- 更新至2.0版,基本完全重写,重点: 改为基于原生LayeredWindow窗体和UpdateLayeredWindo ...
- 继续上篇抢QQ口令红包,抢那招抢不了的红包技巧
- - - - - - - - - - -- - - --长按红包,出现回复,点击回复,那回复里有个表情,直接输入那个表情回复就可以抢了 - - - - - - - - --------------- ...
- SpringMVC传值、转发、重定向例子
练习接收页面参数值 使用request 使用@RequestParam注解 使用实体对象 练习向页面传出数据 使用HttpServletRequest和session 使用ModelAndView对象 ...
- LogBack简易教程
1.简介 LogBack是一个日志框架,它与Log4j可以说是同出一源,都出自Ceki Gülcü之手.(log4j的原型是早前由Ceki Gülcü贡献给Apache基金会的) 1.1 LogBac ...
- drawable微技巧以及layout的小知识
来源:http://blog.csdn.net/guolin_blog/article/details/50727753 最简单的办法是把dp理解成实际物理单位,和英寸.毫米等一样(1dp等于1/16 ...