并查集处理问题的基本思路:如果不是强制在线那么可以倒着处理,把删边改为可爱的加边,然后使用并查集来判断是否联通;
所以可以较为轻松的写出AC代码:
#include <bits/stdc++.h> using namespace std; int n,m; int f[1000010]; struct littlestar{ int to; int nxt; }star[2000010]; int head[2000010],cnt; inline void add(int u,int v) { star[++cnt].to=v; star[cnt].nxt=head[u]; head[u]=cnt; } int ask[1000010]; inline int zhaobaba(int x) { if(f[x]==x){ return x; } return f[x]=zhaobaba(f[x]); } int bo[1000010]; int vis[1000010]; int lala[1000010]; int main() { cin>>n>>m; for(register int i=1;i<=n;i++){ f[i]=i; } for(register int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } int k; cin>>k; for(register int i=1;i<=k;i++){ scanf("%d",&ask[i]); bo[ask[i]]=1; } int ans=n-k; for(register int u=1;u<=n;u++){ if(bo[u]) continue; else{ for(register int i=head[u];i;i=star[i].nxt){ int v=star[i].to; if(bo[v]) continue; int fx=zhaobaba(u); int fy=zhaobaba(v); if(fx!=fy){ f[fy]=fx; --ans; } } } } for(register int u=k;u>=1;u--){ lala[u+1]=ans; ++ans; bo[ask[u]]=0; for(register int i=head[ask[u]];i;i=star[i].nxt){ int v=star[i].to; if(bo[v]) continue; int fx=zhaobaba(ask[u]); int fy=zhaobaba(v); if(fx!=fy){ f[fy]=fx; if(!vis[fy]){ --ans; vis[fy]=1; } } } } lala[1]=ans; for(register int i=1;i<=k+1;i++){ printf("%d\n",lala[i]); } }