题目:https://www.luogu.org/problemnew/show/P4092
利用并查集,倒序离线,那么从倒序来看被撤销标记的点就再也不会被标记,所以用并查集跳过;
莫名其妙的WA,调了一晚上,好像是dfs的地方有问题,莫名其妙的;注释掉的是WA的,现有的可以A,不知怎的。
代码如下:
#include<iostream> #include<cstdio> using namespace std; int const MAXN=100005; int n,q,head[MAXN],ct,fa[MAXN],ans[MAXN],as,cnt[MAXN],sta[MAXN],f[MAXN]; bool b[MAXN]; struct N{ int to,next; N(int t=0,int n=0):to(t),next(n) {} }edge[MAXN<<1]; int find(int x) { if(x==fa[x])return x; return fa[x]=find(fa[x]); } //void dfs(int x) //{ // for(int i=head[x];i;i=edge[i].next) // { // int u=edge[i].to; // if(u==f[x])continue; //// if(!fa[u])fa[u]=x; // f[u]=x; // dfs(u); // } //} void dfs(int u,int x) { f[x]=u; for(int i=head[x];i;i=edge[i].next) { int v=edge[i].to; if(v==u)continue; dfs(x,v); } } int main() { scanf("%d%d",&n,&q); for(int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); edge[++ct]=N(y,head[x]);head[x]=ct; edge[++ct]=N(x,head[y]);head[y]=ct; } for(int i=1;i<=q;i++) { char dc[10]; cin>>dc; cin>>sta[i]; if(dc[0]=='C')cnt[sta[i]]++,b[i]=1; } dfs(1,1); cnt[1]=1; for(int i=1;i<=n;i++)//! { if(cnt[i])fa[i]=i; else fa[i]=f[i]; } for(int k=q;k;k--) { int x=sta[k]; if(b[k]==0)ans[++as]=find(x); else { cnt[x]--; // if(!cnt[x])fa[x]=find(f[x]); if(!cnt[x])fa[x]=f[x];// } } for(int i=as;i;i--) printf("%d ",ans[i]); return 0; }