BZOJ - 1015 【逆向并查集】

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <bitset>
 6 #include <vector>
 7 #include <queue>
 8 #include <stack>
 9 #include <cmath>
10 #include <list>
11 #include <set>
12 #include <map>
13 #define rep(i,a,b) for(int i = a;i <= b;++ i)
14 #define per(i,a,b) for(int i = a;i >= b;-- i)
15 #define mem(a,b) memset((a),(b),sizeof((a)))
16 #define FIN freopen("in.txt","r",stdin)
17 #define FOUT freopen("out.txt","w",stdout)
18 #define IO ios_base::sync_with_stdio(0),cin.tie(0)
19 #define mid ((l+r)>>1)
20 #define ls (id<<1)
21 #define rs ((id<<1)|1)
22 #define N 400010
23 #define INF 0x3f3f3f3f
24 #define INFF ((1LL<<62)-1)
25 using namespace std;
26 typedef long long LL;
27 typedef pair<int, int> PIR;
28 const double eps = 1e-8;
29
30 int n, m, u, v, t, k[N], f[N], ans[N];
31 vector <int> G[N];
32 bool vis[N];
33 int getfa(int x){
34     return f[x] == x ? x : f[x] = getfa(f[x]);
35 }
36 int main()
37 {
38     //FIN;
39     scanf("%d %d", &n, &m);
40     rep(i, 1, m){
41         scanf("%d %d", &u, &v);
42         G[u].push_back(v);
43         G[v].push_back(u);
44     }
45     scanf("%d", &t);
46     rep(i, 1, t)    { scanf("%d", &k[i]); vis[k[i]] = true; }
47     rep(i, 0, n)    f[i] = i;
48
49     int res = n-t;
50     rep(i, 0, n-1){
51         if(vis[i])  continue;
52         int x = getfa(i);
53         rep(j, 0, (int)G[i].size()-1){
54             if(vis[G[i][j]])    continue;
55             int y = getfa(G[i][j]);
56             if(x != y)  { f[y] = x; res--; }
57         }
58     }
59     /*int res = 0;
60     rep(i, 0, n-1)  { if(!vis[i] && getfa(i) == i)  res++; }*/
61     per(i, t, 0){
62         ans[i] = res++;
63         vis[k[i]] = false;
64         int x = getfa(k[i]);
65         rep(j, 0, (int)G[k[i]].size()-1){
66             if(vis[G[k[i]][j]]) continue;
67             int y = getfa(G[k[i]][j]);
68             if(x != y){
69                 f[y] = x;
70                 res--;
71             }
72         }
73     }
74     rep(i, 0, t)    printf("%d\n", ans[i]);
75     return 0;
76 }

时间: 2024-10-24 16:19:20

BZOJ - 1015 【逆向并查集】的相关文章

BZOJ - 1015【并查集】

1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 5721  Solved: 2639[Submit][Status][Discuss] Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的 机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道互相直 接或间接地连接. 但好景不长,很快帝国

BZOJ 1015 星球大战 并查集+离线

这道题说来真是艰辛,从一开始的RE,到RE,到刚刚的WA,再到AC. 这只能说明我进步的历程,还有我需要不断的加强努力.这道题思路不难,从很久前在黑书中并查集一节就能找到解题的踪影,因为并查集只能并,分不了,所以我们就得离线,倒过来写.只不过这道题真的得审好题目,它问的是剩下的星球中有多少个连通分量,不要搞错了.大概就是这个样子了,加油. 1 #include<cstdio> 2 #include<iostream> 3 #define rep(i,j,k) for(int i=

HDU 4496 D-City(逆向并查集)

http://acm.hdu.edu.cn/showproblem.php?pid=4496 题意: 给出n个顶点m条边的图,每次选择一条边删去,求每次删边后的连通块个数. 思路: 离线处理删边,从后往前处理变成加边,用并查集维护连通块个数.其实这题和BZOJ 1015差不多. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 6 int n, m,

BZOJ 1050 旅行(并查集)

很好的一道题. 首先注意,要使的s到t的路径上最大边/最小边的值最小.我们可以尝试一下二分并验证答案. 但是不能二分最大边/最小边. 我们可以二分 最小边的权值.于是算法就出来了. 首先把边权排序.然后枚举最小的边,再依次添加不小于该边的边,直到s和t联通.用并查集维护即可. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include &l

BZOJ 3454 家族 并查集

题目大意:给定一张无向图,每个点有边权,给每个联通块大小一个喜爱度,求一个最小的区间,使保留这个区间内的所有边权的边时喜爱度之和最大 n<=1000,m<=5000 脑残没法治系列-- 如果暴力枚举区间并每次计算喜爱度,时间复杂度为O(nm^2),超时 固定一个左端点,将右端点右移,每次用并查集加边并维护喜爱度之和,时间复杂度O(m^2) 然后这题就做完了= = #include <cstdio> #include <cstring> #include <iost

Connections in Galaxy War——逆向并查集

题目链接 题意: 首先给定一个n 然后给你 n个数 表示 每个恒星的能量大小 p[i] 然后给定一个m 然后输入m 条恒星之间的连接关系 再给定一个q  q行 如果 query x 表示查询与 x 号恒星连接并且能量最多的恒星编号 如果 destroy x y 表示破环 x恒星与y恒星 之间的连接 题解: 传统的做法是先把输入的点加入并查集建立关系,然后开始判断询问,遇到destroy就将那两个点之间的关系断开,但是很明显,这样很难做到将其连接关系断开 正难则反 我们先把未被destroy的恒星

逆向并查集 HYSBZ1015星球大战starwar

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

BZOJ 2503 相框 并查集

题目大意:给定一张无向图,每次可以进行以下两种操作: 1.将一个点分裂成一些点,原先这个点连接的每条边任选一个新点进行连接 2.将两个度数为1的点合并为1个点 求将这个图变成一个环的最小操作次数 首先我们考虑拆 由于终态每个点度数最多为2,因此我们将每个度数大于2的点都拆成一些度数为2的点,如果有零头,留下一个度数为1的点 由欧拉通路的相关结论可知,按照这种拆法,一个有k(k>=2)个奇度数点的连通块存在一种方案可以被拆成k2条链,一个全是偶度数点的连通块可以被拆成一个环 然后如果得到的连通块不

Connections in Galaxy War(逆向并查集)

Connections in Galaxy War http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3563 Time Limit: 3 Seconds      Memory Limit: 32768 KB In order to strengthen the defense ability, many stars in galaxy allied together and built many bidirectional