[BZOJ]4405: [wc2016]挑战NPC(带花树)
带花树模板
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline int read() { int x;char c; while((c=getchar())<'0'||c>'9'); for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=x*10+c-'0'; return x; } #define MN 600 #define ME 100000 #define ms(a) memset(a,0,sizeof(a)) struct edge{int nx,t;}e[ME*2+5]; int h[MN+5],en,mat[MN+5],nx[MN+5],mk[MN+5],f[MN+5],q[MN+5],qn,u[MN+5],cnt; inline void ins(int x,int y) { e[++en]=(edge){h[x],y};h[x]=en; e[++en]=(edge){h[y],x};h[y]=en; } int gf(int k){return f[k]?f[k]=gf(f[k]):k;} int lca(int x,int y) { for(++cnt;;swap(x,y))if(x) { x=gf(x); if(u[x]==cnt)return x; u[x]=cnt; x=nx[mat[x]]; } } void group(int x,int r) { while(x!=r) { int a=mat[x],b=nx[a]; if(gf(b)!=r)nx[b]=a; if(mk[a]>1)mk[q[++qn]=a]=1; if(mk[b]>1)mk[q[++qn]=b]=1; if(gf(x)!=gf(a))f[gf(x)]=gf(a); if(gf(a)!=gf(b))f[gf(a)]=gf(b); x=b; } } bool aug(int x) { int i,j,y,r; ms(nx);ms(mk);ms(f); for(mk[q[i=qn=0]=x]=1;i<=qn;++i)for(j=h[x=q[i]];j;j=e[j].nx) { y=e[j].t; if(mat[x]==y||gf(x)==gf(y)||mk[y]>1)continue; if(mk[y]) { r=lca(x,y); if(gf(x)!=r)nx[x]=y; if(gf(y)!=r)nx[y]=x; group(x,r);group(y,r); } else if(!mat[y]) { for(nx[y]=x,i=y;i;i=y) { x=nx[i];y=mat[x]; mat[i]=x;mat[x]=i; } return true; } else { nx[y]=x;mk[y]=2; mk[q[++qn]=mat[y]]=1; } } return false; } int main() { int T=read(),n,m,e,x,y; while(T--) { n=read();m=read();e=read(); ms(h);en=0;ms(mat); for(x=1;x<=m;++x)ins(n+(x-1)*3+1,n+(x-1)*3+2); while(e--) { x=read();y=read(); ins(x,n+(y-1)*3+1); ins(x,n+(y-1)*3+2); ins(x,n+(y-1)*3+3); } for(x=1,y=-n;x<=n+3*m;++x)if(!mat[x]&&aug(x))++y; printf("%d\n",y); } }