延迟操作和反向操作,拆查集反向操作是并查集
此题咋一看是拆查集,但拆查集反过来是并查集(即反向操作)
反向操作需要延迟操作
#include<bits/stdc++.h> using namespace std; int const N=5e2+7; int n,m,k,cnt; vector<int>v[N]; int vis[N],op[N],f[N],num[N]; int find(int x){ return f[x]==x?x:f[x]=find(f[x]); //以后RE的时候,检查一下递归 } void merge(int x,int y){ f[find(x)]=find(y); } int main(){ cin >> n >> m; for(int i=1,a,b;i<=m;++i){ cin >> a >> b; v[a].push_back(b); v[b].push_back(a); } cin >> k; for(int i=1;i<=k;++i){ cin >> op[i];vis[op[i]]=1; } for(int i=0;i<n;++i) f[i]=i; vector<int>::iterator it; for(int i=0;i<n;++i){ if(vis[i]) continue; for(it=v[i].begin();it!=v[i].end();++it){ if(vis[*it]) continue; if(find(i)!=find(*it)) merge(i,*it); } } for(int i=k;i>=1;--i){ int j=op[i]; for(it=v[j].begin();it!=v[j].end();++it){ if(vis[*it]) continue; if(find(j)!=find(*it)) num[j]++,merge(j,*it); } vis[op[i]]=0; } for(int i=1;i<=k;++i){ if(num[op[i]]>=2) printf("Red Alert: City %d is lost!\n",op[i]); else printf("City %d is lost.\n",op[i]); } if(k==n) cout << "Game Over."; return 0; }