[BZOJ]4405: [wc2016]挑战NPC(带花树)

时间:2021-09-06 21:49:57

带花树模板

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=x*+c-'';
return x;
}
#define MN 600
#define ME 100000
#define ms(a) memset(a,0,sizeof(a))
struct edge{int nx,t;}e[ME*+];
int h[MN+],en,mat[MN+],nx[MN+],mk[MN+],f[MN+],q[MN+],qn,u[MN+],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]>)mk[q[++qn]=a]=;
if(mk[b]>)mk[q[++qn]=b]=;
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=]=x]=;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]>)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]=;
mk[q[++qn]=mat[y]]=;
}
}
return false;
}
int main()
{
int T=read(),n,m,e,x,y;
while(T--)
{
n=read();m=read();e=read();
ms(h);en=;ms(mat);
for(x=;x<=m;++x)ins(n+(x-)*+,n+(x-)*+);
while(e--)
{
x=read();y=read();
ins(x,n+(y-)*+);
ins(x,n+(y-)*+);
ins(x,n+(y-)*+);
}
for(x=,y=-n;x<=n+*m;++x)if(!mat[x]&&aug(x))++y;
printf("%d\n",y);
}
}