您的位置:首页 > 运维架构

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

2015-02-19 23:33 330 查看
水。

/**************************************************************
Problem: 1015
User: idy002
Language: C++
Result: Accepted
Time:2072 ms
Memory:14796 kb
****************************************************************/

#include <cstdio>
#include <vector>
#define maxn 400010
using namespace std;

int fa[maxn];
void init( int n ) {
for( int i=0; i<=n; i++ ) fa[i] = i;
}
int find( int a ) {
return fa[a]==a ? a : fa[a]=find(fa[a]);
}
void unon( int a, int b ) {
a = find(a);
b = find(b);
fa[a] = b;
}

int n, m;
vector<int> g[maxn];
bool vis[maxn];
int ans[maxn], opt[maxn], tot, cnt;

int main() {
scanf( "%d%d", &n, &m );
for( int i=1,u,v; i<=m; i++ ) {
scanf( "%d%d", &u, &v );
u++, v++;
g[u].push_back(v);
g[v].push_back(u);
}
scanf( "%d", &tot );
for( int i=1; i<=tot; i++ ) {
scanf( "%d", opt+i );
opt[i]++;
vis[opt[i]] = true;
}

init(n);
for( int u=1; u<=n; u++ ) {
if( vis[u] ) continue;
for( int t=0; t<g[u].size(); t++ ) {
int v = g[u][t];
if( vis[v] ) continue;
unon(u,v);
}
}
cnt = 0;
for( int i=1; i<=n; i++ ) if( fa[i]==i && !vis[i]) cnt++;

for( int i=tot; i>=1; i-- ) {
ans[i] = cnt;
cnt++;
int u = opt[i];
vis[u] = false;
for( int t=0; t<g[u].size(); t++ ) {
int v = g[u][t];
if( vis[v] ) continue;
if( find(u)!=find(v) ) {
unon(u,v);
cnt--;
}
}
}
ans[0] = cnt;
for( int i=0; i<=tot; i++ )
printf( "%d\n", ans[i] );
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: