带花树博弈
#include<bits/stdc++.h>
using namespace std;const int N=6e2+7,M=N*N;char s[N];
struct data{int to,next;}e[M<<1];int head[N],cnt,ban[N],pre[N],match[N],fa[N],q[N],t,w,x,y,z,vis[N],tim,dfn[N],n,m,i,j,ans;
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void ins(int u,int v){e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}
void insert(int u,int v){ins(u,v);ins(v,u);}
int lca(int x,int y){
++tim;x=find(x);y=find(y);
while(dfn[x]!=tim){
dfn[x]=tim;
x=find(pre[match[x]]);
if(y)swap(x,y);
}return x;
}
void Blossom(int x,int y,int z){
while(find(x)!=z){
pre[x]=y,y=match[x];
if(vis[y]==2)vis[y]=1,q[w++]=y;
if(find(x)==x)fa[x]=z;
if(find(y)==y)fa[y]=z;
x=pre[y];
}
}
bool Aug(int S){
for(int i=1;i<=n;++i)fa[i]=i,vis[i]=pre[i]=0;
t=0;w=1;q[0]=S;vis[S]=1;
while(t!=w){
x=q[t++];
for(int i=head[x];i;i=e[i].next){
y=e[i].to;
if(ban[y]||find(x)==find(y)||vis[y]==2)continue;
if(!vis[y]){
vis[y]=2;pre[y]=x;
if(!match[y]){
for(int x=y,lst;x;x=lst)
lst=match[pre[x]],match[x]=pre[x],match[pre[x]]=x;
return true;
}
vis[match[y]]=1,q[w++]=match[y];
}else{
z=lca(x,y);
Blossom(x,y,z);
Blossom(y,x,z);
}
}
}return false;
}
int main(){
for(scanf("%d",&n),i=1;i<=n;++i)for(scanf("%s",s+1),j=1;j<=n;++j)if(s[j]=='0')ins(i,j);
for(i=1;i<=n;++i)if(!match[i])Aug(i);
for(i=1;i<=n;++i)if(match[i]==0)printf("1");
else{
j=match[i];
match[i]=match[j]=0;
ban[i]=1;
Aug(j);
ban[i]=0;
if(match[j]!=0)printf("1");
else{
printf("0");
Aug(j);
}
}
}