Code:
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=300;
const int INF=1000000+233;
int C[maxn][maxn],is[maxn],home[maxn],idx[maxn];
int s,t;
struct Edge{
int from,to,cap;
Edge(int u,int v,int c):from(u),to(v),cap(c){}
};
struct Dicnic{
vector<Edge>edges;
vector<int>G[maxn];
queue<int>Q;
int d[maxn],vis[maxn],current[maxn];
void init()
{
edges.clear();
for(int i=0;i<maxn;++i)G[i].clear();
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
memset(current,0,sizeof(current));
}
void add_edge(int u,int v,int c)
{
edges.push_back(Edge(u,v,c));
edges.push_back(Edge(v,u,0));
int m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
int BFS()
{
memset(vis,0,sizeof(vis));
Q.push(s);vis[s]=1,d[s]=0;
while(!Q.empty())
{
int u=Q.front();Q.pop();
int siz=G[u].size();
for(int i=0;i<siz;++i)
{
Edge r=edges[G[u][i]];
if(!vis[r.to]&&r.cap>0)
{
vis[r.to]=1,d[r.to]=d[u]+1;
Q.push(r.to);
}
}
}
if(vis[t])return 1;
return 0;
}
int dfs(int x,int cur)
{
if(x==t)return cur;
int f,flow=0;
int siz=G[x].size();
for(int i=current[x];i<siz;++i)
{
current[x]=i;
int u=G[x][i];
Edge r=edges[u];
if(d[r.to]==d[x]+1&&r.cap>0)
{
f=dfs(r.to,min(cur,r.cap));
if(f>0)
{
cur-=f,flow+=f;
edges[u].cap-=f,edges[u^1].cap+=f;
}
}
if(cur==0)break;
}
return flow;
}
int maxflow()
{
int flow=0;
while(BFS())
{
memset(current,0,sizeof(current));
flow+=dfs(s,INF);
}
return flow;
}
}op;
void init()
{
memset(is,0,sizeof(is));
memset(home,0,sizeof(home));
memset(C,0,sizeof(C));
}
int main()
{
//freopen("in.txt","r",stdin);
int T,n;
scanf("%d",&T);
while(T--)
{
op.init();
init();
int num=0,cc=0;
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
int a;scanf("%d",&a);
if(a)
{
is[i]=1,num+=1,idx[i]=num;
}
}
for(int i=1;i<=n;++i)
{
int a;scanf("%d",&a);
if(is[i]&&a)home[i]=1,cc+=1;
}
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)scanf("%d",&C[i][j]);
s=0,t=188;
for(int i=1;i<=n;++i)
{
if(is[i])op.add_edge(n+idx[i],t,1);
if(!home[i])
{
op.add_edge(s,i,1);
if(is[i])op.add_edge(i,idx[i]+n,1);
for(int j=1;j<=n;++j)
{
if(C[i][j]&&is[j])op.add_edge(i,n+idx[j],1);
}
}
}
int ans=op.maxflow();
if(ans==n-cc)printf("^_^\n");
else printf("T_T\n");
}
return 0;
}