Codeforces292D(SummerTrainingDay06-L 前缀并查集)
D. Connected Components
We already know of the large corporation where Polycarpus works as a system administrator. The computer network there consists of n computers and m cables that connect some pairs of computers. In other words, the computer network can be represented as some non-directed graph with n nodes and m edges. Let's index the computers with integers from 1 to n, let's index the cables with integers from 1 to m.
Polycarpus was given an important task — check the reliability of his company's network. For that Polycarpus decided to carry out a series of k experiments on the computer network, where the i-th experiment goes as follows:
- Temporarily disconnect the cables with indexes from li to ri, inclusive (the other cables remain connected).
- Count the number of connected components in the graph that is defining the computer network at that moment.
- Re-connect the disconnected cables with indexes from li to ri (that is, restore the initial network).
Help Polycarpus carry out all experiments and for each print the number of connected components in the graph that defines the computer network through the given experiment. Isolated vertex should be counted as single component.
Input
The first line contains two space-separated integers n, m (2 ≤ n ≤ 500; 1 ≤ m ≤ 104) — the number of computers and the number of cables, correspondingly.
The following m lines contain the cables' description. The i-th line contains space-separated pair of integers xi, yi(1 ≤ xi, yi ≤ n; xi ≠ yi) — the numbers of the computers that are connected by the i-th cable. Note that a pair of computers can be connected by multiple cables.
The next line contains integer k (1 ≤ k ≤ 2·104) — the number of experiments. Next k lines contain the experiments' descriptions. The i-th line contains space-separated integers li, ri (1 ≤ li ≤ ri ≤ m) — the numbers of the cables that Polycarpus disconnects during the i-th experiment.
Output
Print k numbers, the i-th number represents the number of connected components of the graph that defines the computer network during the i-th experiment.
Examples
input
6 5
1 2
5 4
2 3
3 1
3 6
6
1 3
2 5
1 5
5 5
2 4
3 3
output
4
5
6
3
4
2
题意:给出n(<=500)个点和m(<=1e4)条边,形成一个图,查询k(<=1e4)次,对于每个查询,有l和r,输出删除编号[l,r]区间内的边后形成的连通块的个数。
思路:连通块肯定想到用并查集去维护。然后看到n比较小,所以可能可以每次查询里面复杂度带有n。
因为删边用并查集不是很好维护,所以我们可能要想到能不能避免边的删除,那么很容易的想到前缀和思想。
用dsu1[l]来保存[1,l]前l条边组成的图里面的并查集父节点的情况;
用dsu2[r]来保存[r,n]后r条边组成的图里面的并查集父节点的情况;
那么对于每一次查询[l,r]我只要把dsu1[l-1]和dsu2[r+1]的并查集父节点情况再次合并,也就是把两个并查集数组合并,那么就能得到新的并查集,这就是此刻图的情况了。
//=============================================//
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| -_- |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | | \\\ - /// | | | //
// | \_| ''\---/'' | / | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . __ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - `: | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
//======`-.____`-.___\_____/___.-`____.-'======//
// `=---=' //
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//
// 佛祖保佑 永无BUG //
// 本模块已经经过开光处理,绝无可能再产生bug //
//=============================================//
//2017-09-05
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int N = ;
const int M = ; int n, m;
struct DSU{
int fa[N];
void init(){
for(int i = ; i < N; i++)
fa[i] = i;
}
int getfa(int x){
if(x == fa[x])return x;
return fa[x] = getfa(fa[x]);
}
void merge(int a, int b){
int af = getfa(a);
int bf = getfa(b);
if(af != bf){
fa[bf] = af;
}
}
}dsu1[M], dsu2[M];//dsu1[i]表示由前i条边生成的并查集,dsu2[i]表示由后i条边生成的并查集 int work(DSU ldsu, DSU rdsu){
//将两棵并查集合并
for(int i = ; i <= n; i++)
ldsu.merge(i, rdsu.getfa(i));
int ans = ;
for(int i = ; i <= n; i++)
if(ldsu.fa[i] == i)
ans++;
return ans;
}
pair<int, int> line[M];
int main()
{
std::ios::sync_with_stdio(false);
cin.tie();
//freopen("inputL.txt", "r", stdin);
while(cin>>n>>m){
for(int i = ; i <= m; i++)
cin>>line[i].first>>line[i].second;
dsu1[].init();
for(int i = ; i <= m; i++){
dsu1[i] = dsu1[i-];
dsu1[i].merge(line[i].first, line[i].second);
}
dsu2[m+].init();
for(int i = m; i >= ; i--){
dsu2[i] = dsu2[i+];
dsu2[i].merge(line[i].first, line[i].second);
}
int k, l, r;
cin>>k;
while(k--){
cin>>l>>r;
cout<<work(dsu1[l-], dsu2[r+])<<endl;
}
} return ;
}
Codeforces292D(SummerTrainingDay06-L 前缀并查集)的更多相关文章
- 【HDU 3038】 How Many Answers Are Wrong (带权并查集)
How Many Answers Are Wrong Problem Description TT and FF are ... friends. Uh... very very good frien ...
- 【BZOJ】1202: [HNOI2005]狡猾的商人(并查集+前缀和)
http://www.lydsy.com/JudgeOnline/problem.php?id=1202 用并查集+前缀和. 前缀和从后向前维护和,并查集从前往后合并 对于询问l, r 如果l-1和r ...
- AcWing:239. 奇偶游戏(前缀和 + 离散化 + 带权并查集 + 异或性质 or 扩展域并查集 + 离散化)
小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...
- BZOJ-1202 狡猾的商人 并查集+前缀和
我记得这个题,上次之前做的时候没改完,撂下了,今天突然想改发现,woc肿么A 了= =看来是我记错了.. 1202: [HNOI2005]狡猾的商人 Time Limit: 10 Sec Memory ...
- 【bzoj 1202】[HNOI2005] 狡猾的商人(图论--带权并查集+前缀和)
题意:一个账本记录了N个月以来的收入情况,现在有一个侦探员不同时间偷看到M段时间内的总收入,问这个账本是否为假账. 解法:带权并查集+前缀和. 判断账本真假是通过之前可算到的答案与当前读入的值是否 ...
- 【二分图】【并查集】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem L. Canonical duel
给你一个网格(n<=2000,m<=2000),有一些炸弹,你可以选择一个空的位置,再放一个炸弹并将其引爆,一个炸弹爆炸后,其所在行和列的所有炸弹都会爆炸,连锁反应. 问你所能引爆的最多炸 ...
- 51nod 1204 Parity(并查集应用)
1204 Parity 题目来源: Ural 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 你的朋友写下一串包含1和0的串让你猜,你可以从中选择一个连续的子串 ...
- Educational Codeforces Round 51 (Rated for Div. 2) G. Distinctification(线段树合并 + 并查集)
题意 给出一个长度为 \(n\) 序列 , 每个位置有 \(a_i , b_i\) 两个参数 , \(b_i\) 互不相同 ,你可以进行任意次如下的两种操作 : 若存在 \(j \not = i\) ...
- luogu 2294 狡猾的商人 带权并查集
此题做法多啊 带权并查集,区间dp,前缀和,差分约束 1.自己写的前缀和, 11 #include<bits/stdc++.h> #define rep(i,x,y) for(regist ...
随机推荐
- [学习笔记]CDQ分治和整体二分
序言 \(CDQ\) 分治和整体二分都是基于分治的思想,把复杂的问题拆分成许多可以简单求的解子问题.但是这两种算法必须离线处理,不能解决一些强制在线的题目.不过如果题目允许离线的话,这两种算法能把在线 ...
- Linux学习笔记-基本操作1
1>. 命令解析器2>. Linux快捷键3>. Linux 系统目录结构4>. 用户目录5>. 文件和目录操作6>. 文件和目录的属性7>. 文件权限, 用 ...
- JavaScript 那些不经意间发生的数据类型自动转换
JavaScript可以自由的进行数据类型转换,也提供了多种显式转换的方式.但是更多的情况下,是由JavaScript自动转换的,当然这些转换遵循着一定的规则,了解数据类型自由转换的规则是非常必要的. ...
- Centos Android开发环境配置-Android Tools -android list sdk --extended --all
Centos Android开发环境配置-Android Tools -android list sdk --extended --all 安装完Android Tools后执行 android ...
- Sublime text3 Package Control不能使用
Package Control打开时提示"There are no availabel for installation"的两个处理办法: 第一种: ping一下sublime的服 ...
- Git学习系列之CentOS上安装Git详细步骤(图文详解)
前言 最早Git是在Linux上开发的,很长一段时间内,Git也只能在Linux和Unix系统上跑.不过,慢慢地有人把它移植到了Windows上.现在,Git可以在Linux.Unix.Mac和Win ...
- typedef在C和C++的区别?
一.struct定义结构体1.先声明结构体类型再定义变量名struct name{ member ..};name A;... 如:struct student{ int a;};student st ...
- 探讨e.target与e.currentTarget
target与currentTarget两者既有区别,也有联系,那么我们就来探讨下他们的区别吧,一个通俗易懂的例子解释一下两者的区别: <!DOCTYPE html> <html&g ...
- Shell脚本 | 一键获取安卓应用活动名
上篇文章提到,启动时间的计算需要用到应用启动页的活动名(Activity_Name). 如何获取活动名呢?通常有如下几种方式: 1.询问 Dev 同事 2.adb logcat ActivityMan ...
- python 生成唯一识别码
import uuid identity = str(uuid.uuid4()).encode('ascii')