DZY Loves Graph
按秩合并的并查集支持删边操作。
附代码
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; inline void read(int &x){ x=0;char ch;bool flag = false; while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true; while(x=10*x+ch-'0',ch=getchar(),ch > '!');if(flag) x=-x; } const int maxn = 510010; int fa[maxn],siz[maxn]; inline int find(int x){ while(fa[x] != x) x = fa[x]; return x; } int ope[maxn]; char s[12]; struct ope{ int op,u,v; }op[maxn]; ll ans[maxn],sum[maxn]; int main(){ int n,m;read(n);read(m); for(int i=1;i<=n;++i) fa[i] = i,siz[i] = 1; for(int i=1;i<=m;++i){ scanf("%s",s); if(*s == 'A'){ op[i].op = 1; read(op[i].u); read(op[i].v); }else if(*s == 'D'){ op[i].op = 2; read(op[i].u); }else if(*s == 'R') op[i].op = 3; } int ecnt = 0,nodecnt = n; for(int i=1;i<=m;++i){ if(op[i].op == 1){ if(op[i+1].op == 3){ if(nodecnt == 1) printf("%lld\n",ans[ecnt]); else if(nodecnt == 2){ int x = find(op[i].u); int y = find(op[i].v); if(x == y) puts("0"); else printf("%lld\n",sum[ecnt] + i); }else puts("0"); printf("%lld\n",ans[ecnt]); ++ i; }else{ ans[ecnt+1] = ans[ecnt]; sum[ecnt+1] = sum[ecnt]; ++ecnt; int x = find(op[i].u); int y = find(op[i].v); if(x == y){ printf("%lld\n",ans[ecnt]); ope[ecnt] = 0; continue; } if(siz[x] > siz[y]) swap(x,y); fa[x] = y;siz[y] += siz[x];ope[ecnt] = x; sum[ecnt] += i; if(--nodecnt == 1) ans[ecnt] = sum[ecnt]; printf("%lld\n",ans[ecnt]); } }else if(op[i].op == 2){ if(op[i+1].op == 3){ printf("%lld\n",ans[ecnt-op[i].u]); ++ i; printf("%lld\n",ans[ecnt]); }else{ for(int j=0;j<op[i].u;++j){ if(ope[ecnt] != 0){ int x = ope[ecnt]; ++ nodecnt; siz[fa[x]] -= siz[x]; fa[x] = x; }-- ecnt; } printf("%lld\n",ans[ecnt]); } } } return 0; }
河西,河东,穷少年