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 }
View Code

 

posted @ 2015-02-19 23:33  idy002  阅读(253)  评论(0编辑  收藏  举报