大家都说是裸题。。。
圆方树把图变成树,看虚树上有多少圆点即可
#include#include #include #include #include #include #include using namespace std;const int _=1e2;const int maxn=1e5+_;const int maxm=2*1e5+_;int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){ if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} return x*f;}void write(int x){ if(x>=10)write(x/10); putchar(x%10+'0');}struct node{ int x,y,next;}a[2*2*maxm];int len,last[2*maxn];void ins(int x,int y){// printf("%d %d\n",x,y); len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len;}//-----------------------------------------def----------------------------------------------------int vz,dfn[maxn],low[maxn];int top,sta[2*2*maxn];int cnt;vector vec[maxn];void V_DCC(int x){ dfn[x]=low[x]=++vz; sta[++top]=x; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(dfn[y]==0) { V_DCC(y); low[x]=min(low[x],low[y]); if(low[y]>=dfn[x]) { cnt++;vec[cnt].clear(); int i; do { i=sta[top];top--; vec[cnt].push_back(i); }while(i!=y); vec[cnt].push_back(x); } } else low[x]=min(low[x],dfn[y]); }}void maketree(int id){ len=1;memset(last,0,sizeof(last)); for(int i=1;i<=cnt;i++) { id++; for(int j=0;j =0;i--) if(dep[x]-dep[y]>=(1< =0;i--) if(dep[x]>=(1< 1&&LCA(p[i],sta[top-1])!=sta[top-1]) ans+=num[sta[top]]-num[sta[top-1]],top--; if(top==1||LCA(p[i],sta[top])!=sta[top-1]) { int lca=LCA(p[i],sta[top]); ans+=num[sta[top]]-num[lca],top--; sta[++top]=lca; sta[++top]=p[i]; } else { ans+=num[sta[top]]-num[sta[top-1]],top--; sta[++top]=p[i]; } } while(top>1) ans+=num[sta[top]]-num[sta[top-1]],top--; ans+=num[sta[top]]-num[fa[0][sta[top]]];}int main(){ freopen("a.in","r",stdin); freopen("a.out","w",stdout); int T; T=read(); while(T--) { int n,m,x,y; n=read(),m=read(); len=1;memset(last,0,sizeof(last)); for(int i=1;i<=m;i++) { x=read(),y=read(); ins(x,y),ins(y,x); }// puts(""); vz=top=cnt=0; memset(dfn,0,sizeof(dfn)); V_DCC(1); maketree(n); num[1]=1;lim=n;dfs(1);// puts(""); //....pre..... int Q; Q=read(); while(Q--) { m=read(); for(int i=1;i<=m;i++)p[i]=read(); ans=0; VirtualTree(m); write(ans-m),putchar('\n'); }// break; } return 0;}