1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| const int maxn=5e5+5; int head[maxn]; int to[maxn*2],ew[maxn*2],nex[maxn*2],tot; inline void _addedge(int u,int v,int w){to[++tot]=v,ew[tot]=w,nex[tot]=head[u],head[u]=tot;} inline void addedge(int u,int v,int w){_addedge(u,v,w),_addedge(v,u,w);} void deltree(int rt,int father){ for(int i=head[rt];i;i=nex[i]) if(to[i]!=father) deltree(to[i],rt); head[rt]=0; }
int dep[maxn],dad[maxn],siz[maxn],son[maxn],dfn[maxn],chain[maxn],step; void dfs1(int u,int father){ siz[u]=1; son[u]=0; dad[u]=father; dep[u]=dep[father]+1; for(int i=head[u];i;i=nex[i]){ if(to[i]==father) continue; dfs1(to[i],u); siz[u]+=siz[to[i]]; if(siz[to[i]]>siz[son[u]]) son[u]=to[i]; } } void dfs2(int u,int s){ dfn[u]=++step; chain[u]=s; if(son[u]) dfs2(son[u],s); for(int i=head[u];i;i=nex[i]){ if(to[i]==dad[u]||to[i]==son[u]) continue; dfs2(to[i],to[i]); } } int getlca(int x,int y){ while(chain[x]!=chain[y]) { if(dep[chain[x]]<dep[chain[y]]) swap(x,y); x=dad[chain[x]]; } return dep[x]<dep[y]?x:y; }
bool vt[maxn]; void buildvt(int*vert,int nums,int base){ sort(vert+1,vert+nums+1,[](int x,int y){return dfn[x]<dfn[y];}); int top=0; stk[++top]=1,vt[base+1]=vert[1]==1; rep(i,vert[1]==1?2:1,nums){ int lca=getlca(vert[i],stk[top]); if(lca==stk[top]) {stk[++top]=vert[i],vt[base+vert[i]]=true;continue;} while(dfn[lca]<=dfn[stk[top-1]]) addedge(base+stk[top],base+stk[top-1],0),top--; if(lca!=stk[top]) addedge(base+stk[top],base+lca,0),stk[top]=lca,vt[base+lca]=false; stk[++top]=vert[i],vt[base+vert[i]]=true; } while(top>=2){ addedge(base+stk[top],base+stk[top-1],0); top--; } }
|