题目:星球大战
思路:
反向操作,删点 => 加点,用并查集维护。
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 400000
#define maxm 200000
#define read(x) scanf("%d",&x)
int n,m;
vector<int> g[maxn+5];
int del[maxn+5];
int isdel[maxn+5];
int fa[maxn+5];
vector<int> ans;
int find(int x) {
return fa[x]==-1?x:(fa[x]=find(fa[x]));
}
int main() {
memset(fa,-1,sizeof(fa));
read(n),read(m);
for(int i=1; i<=m; i++) {
int x,y;
read(x),read(y);
x++,y++;
g[x].push_back(y);
g[y].push_back(x);
}
int T;
read(T);
for(int i=1; i<=T; i++) {
read(del[i]);
del[i]++;
isdel[del[i]]=true;
}
for(int i=1; i<=n; i++) {
if(0==isdel[i]) {
int fa1=find(i);
for(int j=0; j<g[i].size(); j++) {
int x=g[i][j];
if(isdel[x]) continue;
int fa2=find(x);
if(fa1!=fa2) {
fa[fa2]=fa1;
}
}
}
}
int len=0;
for(int i=1; i<=n; i++) {
if(0==isdel[i]&&-1==fa[i]) len++;
}
ans.push_back(len);
for(int t=T; t>=1; t--) {
int x=del[t],fa1=find(x);
if(0==isdel[x]) {
ans.push_back(len);
continue;
}
isdel[x]=0;
len++;
for(int i=0;i<g[x].size();i++) {
int y=g[x][i];
if(isdel[y]) continue;
int fa2=find(y);
if(fa1!=fa2) {
len--;
fa[fa2]=fa1;
}
}
ans.push_back(len);
}
for(int i=ans.size()-1;i>=0;i--) {
int x=ans[i];
printf("%d\n",x);
}
return 0;
}