题面
https://www.luogu.org/problem/P4606
题解
又一次被$aysn$吊打。
// luogu-judger-enable-o2 #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #define N 200000 #define ri register int using namespace std; int n,m,q,s,T,cnt,clo; int dfn[N],low[N],stk[N],top,bel[N]; int f[N][25]; int dfin[N],dfou[N],d[N]; vector<int> to[N],syx[N]; int a[N*2],ss[N*2],yy[N],stop,siz[N]; bool vis[N]; bool cmp1(int x,int y){ return dfin[x]<dfin[y]; } bool cmp2(int x,int y){ int k1,k2; if (x>0) k1=dfin[x]; else k1=dfou[-x]; if (y>0) k2=dfin[y]; else k2=dfou[-y]; return k1<k2; } void tarjan(int x,int ff){ dfn[x]=low[x]=++clo; stk[++top]=x; for (ri i=to[x].size()-1;i>=0;i--) if (to[x][i]!=ff) { if (!dfn[to[x][i]]) { tarjan(to[x][i],x); low[x]=min(low[x],low[to[x][i]]); if (low[to[x][i]]>=dfn[x]) { cnt++; int cc; do { cc=stk[top]; syx[cnt].push_back(cc); syx[cc].push_back(cnt); top--; } while (cc!=to[x][i]); syx[cnt].push_back(x); syx[x].push_back(cnt); } } else low[x]=min(dfn[to[x][i]],low[x]); } } void dfs(int x,int ff) { f[x][0]=ff; d[x]=d[ff]+1; yy[x]=yy[ff]+(x<=n); for (ri i=1;i<=20;i++) f[x][i]=f[f[x][i-1]][i-1]; dfin[x]=++cnt; for (ri i=syx[x].size()-1;i>=0;i--) if (syx[x][i]!=ff) dfs(syx[x][i],x); dfou[x]=++cnt; } int lca(int x,int y){ if (d[x]<d[y]) swap(x,y); for (ri i=20;i>=0;i--) if (d[f[x][i]]>=d[y]) x=f[x][i]; if (x==y) return x; for (ri i=20;i>=0;i--) if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; return f[x][0]; } int main(){ scanf("%d",&T); for (ri ti=1;ti<=T;ti++) { scanf("%d %d",&n,&m); int u,v; for (ri i=1;i<=m;i++) { scanf("%d %d",&u,&v); to[u].push_back(v); to[v].push_back(u); } clo=0; top=0; cnt=n; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(bel,0,sizeof(bel)); tarjan(1,1); cnt=0; d[1]=0; yy[1]=0; dfs(1,1); scanf("%d",&q); for (ri ii=1;ii<=q;ii++) { scanf("%d",&s); int t=s; for (ri i=1;i<=s;i++) { scanf("%d",&a[i]); vis[a[i]]=1; } sort(a+1,a+s+1,cmp1); int ns=s; for (ri i=1;i<ns;i++) { int t=lca(a[i],a[i+1]); if (!vis[t]) a[++s]=t,vis[t]=1; } ns=s; for (ri i=1;i<=ns;i++) a[++s]=-a[i]; sort(a+1,a+s+1,cmp2); stop=0; for (ri i=1;i<=s;i++) if (a[i]>0) { ss[++stop]=a[i]; if (a[i]<=n) siz[a[i]]++; } else { stop--; if (stop) siz[ss[stop]]+=(siz[-a[i]]+yy[-a[i]]-(-a[i]<=n)-yy[ss[stop]]); } printf("%d ",siz[a[1]]-t); for (ri i=1;i<=s;i++) if (a[i]>0) siz[a[i]]=0,vis[a[i]]=0; } for (ri i=1;i<=cnt;i++) to[i].clear(); for (ri i=1;i<=cnt;i++) syx[i].clear(); } }