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 }