总之,按照要求连边就对了。裸的最大匹配。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 110
using namespace std;
int a[maxn][maxn],lk[maxn];
int b[maxn],c[maxn];
bool vis[maxn];
int n,m,cnt,ans,T;
bool find(int x)
{
for (int i=1;i<=n;i++)
if (a[x][i] && !vis[i])
{
vis[i]=1;
if (!lk[i] || find(lk[i]))
{
lk[i]=x;
return 1;
}
}
return 0;
}
int main()
{
scanf("%d",&T);
while (T--)
{
memset(a,0,sizeof(a));
memset(lk,0,sizeof(lk));
scanf("%d",&n);
cnt=ans=0;
for (int i=1;i<=n;i++) scanf("%d",&b[i]);
for (int i=1;i<=n;i++) {scanf("%d",&c[i]);if (!b[i] || (b[i] && !c[i])) cnt++;}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
int x;
scanf("%d",&x);
if (x && ((b[i] && !c[i]) || !b[i]) && b[j]) a[i][j]=1;
}
if (b[i] && !c[i]) a[i][i]=1;
}
for (int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
if (find(i)) ans++;
}
if (ans==cnt) printf("^_^\n"); else printf("T_T\n");
}
return 0;
}