bzoj 1015 维护连通块个数,离线并查集

水。

 1 /**************************************************************
 2     Problem: 1015
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:2072 ms
 7     Memory:14796 kb
 8 ****************************************************************/
 9
10 #include <cstdio>
11 #include <vector>
12 #define maxn 400010
13 using namespace std;
14
15 int fa[maxn];
16 void init( int n ) {
17     for( int i=0; i<=n; i++ ) fa[i] = i;
18 }
19 int find( int a ) {
20     return fa[a]==a ? a : fa[a]=find(fa[a]);
21 }
22 void unon( int a, int b ) {
23     a = find(a);
24     b = find(b);
25     fa[a] = b;
26 }
27
28 int n, m;
29 vector<int> g[maxn];
30 bool vis[maxn];
31 int ans[maxn], opt[maxn], tot, cnt;
32
33 int main() {
34     scanf( "%d%d", &n, &m );
35     for( int i=1,u,v; i<=m; i++ ) {
36         scanf( "%d%d", &u, &v );
37         u++, v++;
38         g[u].push_back(v);
39         g[v].push_back(u);
40     }
41     scanf( "%d", &tot );
42     for( int i=1; i<=tot; i++ ) {
43         scanf( "%d", opt+i );
44         opt[i]++;
45         vis[opt[i]] = true;
46     }
47
48     init(n);
49     for( int u=1; u<=n; u++ ) {
50         if( vis[u] ) continue;
51         for( int t=0; t<g[u].size(); t++ ) {
52             int v = g[u][t];
53             if( vis[v] ) continue;
54             unon(u,v);
55         }
56     }
57     cnt = 0;
58     for( int i=1; i<=n; i++ ) if( fa[i]==i && !vis[i]) cnt++;
59
60     for( int i=tot; i>=1; i-- ) {
61         ans[i] = cnt;
62         cnt++;
63         int u = opt[i];
64         vis[u] = false;
65         for( int t=0; t<g[u].size(); t++ ) {
66             int v = g[u][t];
67             if( vis[v] ) continue;
68             if( find(u)!=find(v) ) {
69                 unon(u,v);
70                 cnt--;
71             }
72         }
73     }
74     ans[0] = cnt;
75     for( int i=0; i<=tot; i++ )
76         printf( "%d\n", ans[i] );
77 }

时间: 2024-10-31 17:16:32

bzoj 1015 维护连通块个数,离线并查集的相关文章

2015 ACM/ICPC Asia Regional Changchun Online HDU - 5441 (离线+并查集)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5441 题意:给你n,m,k,代表n个城市,m条边,k次查询,每次查询输入一个x,然后让你一个城市对(u,v)满足两点之间每一条边都不超过x,问有多少对 思路:首先我想到的是dfs求出每个查询小于等于他的一个连通块,然后num*(num-1)就是答案,但是时间只有一秒,这个复杂度是5*1e8,超时了(亲身体验了) 然后我们想这个是离线的,我们可不可以由小到大来推,这样前面的贡献到后面就依然能用了,但是我们

CSUOJ 1601 War (离线并查集求连通块个数)

1601: War Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 130  Solved: 38 [Submit][Status][Web Board] Description AME decided to destroy CH's country. In CH' country, There are N villages, which are numbered from 1 to N. We say two village A and B ar

逆向思维 + 用并查集动态维护连通块的个数——Luogu P1197题解

题目大意: 给你一个 $ n $ 个点的图与 $ m $ 条边,接下来给出一个长度为 $ k $ 个整数,按照给出整数的顺序依次删掉对应编号的点,求出一开始的连通块的个数与接下来每次删除一个点后的连通块的个数.(连通块就是一个点集,这个集合里面的任意两个点都可以互相到达) 思路: 大体思路: 这个题目如果正向考虑会很难做,因为我们要每次维护一个不断删点的图的连通块个数是很难弄的.所以我们要倒着考虑.假如我们把删点的过程倒着考虑,就变成了从最后一个点往前添加进这个图里面的过程.所以这样问题就变成了

P1197 [JSOI2008]星球大战 [删边求连通块个数]

展开 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道互相直接或间接地连接. 但好景不长,很快帝国又重新造出了他的超级武器.凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球.由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来. 现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽

BZOJ 1529 [POI2005]ska Piggy banks(并查集)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1529 [题目大意] 给出一张n个点n条边的有向图,问选取几个点为起点可以遍历全图 [题解] 由于是n条边,因此图为基环森林,选取环上点一定可以到达连通块内所有点, 因此只要统计连通块个数即可. [代码] #include <cstdio> #include <algorithm> using namespace std; const int N=1000100; int

ACM学习历程—Hihocoder 1291 Building in Sandbox(dfs &amp;&amp; 离线 &amp;&amp; 并查集)

http://hihocoder.com/problemset/problem/1291 前几天比较忙,这次来补一下微软笔试的最后一题,这题是这次微软笔试的第四题,过的人比较少,我当时在调试B题,没时间看这一题.不过打过之前一场BestCoder的应该都会有点思路,虽然BC那题是二维,这题是三维的,但是思路应该是一样的,没错,就是离线加并查集. 正过来考虑的时候,发现第一个要求相邻块是好处理的,但是第二个要求能否到达(1000, 1000, 1000)这个条件似乎比较难判断,当时BC上的题根据题

HDU-5441 Travel 离线-并查集

Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 4680    Accepted Submission(s): 1532 Problem Description Jack likes to travel around the world, but he doesn't like to wait. Now, he is t

BZOJ 1050 旅行comf(枚举最小边-并查集)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1050 题意:给出一个带权图.求一条s到t的路径使得这条路径上最大最小边的比值最小? 思路:将边排序.枚举最小边,然后将边一个一个插到并查集里,s和t联通时计算更新答案. struct node { int u,v,w; void get() { RD(u,v,w); } }; int cmp(node a,node b) { return a.w<b.w; } int n,m,s,t;

Codeforces 920E Connected Components? 补图连通块个数

题目链接 题意 对给定的一张图,求其补图的联通块个数及大小. 思路 参考 ww140142. 维护一个链表,里面存放未归入到任何一个连通块中的点,即有必要从其开始进行拓展的点. 对于每个这样的点,从它开始进行 \(bfs\),将未被拓展到的点加入队列,并从链表中删除. 注意:写法上有一点要注意, 在处理完一整个连通块之后,记录下下一个连通块中的第一个点之后,再将最初的 \(src\) 从链表中删除.若一开始便删除,则会造成链表脱节. Code #include <bits/stdc++.h>