题解:
匈牙利算法的经典题。。。不再赘述。
代码如下:
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
const int maxn=55,maxm=2505;
int T,n,m,tot,ans,a[maxn],b[maxn],girl[maxn],lnk[maxn],son[maxm],nxt[maxm];
bool used[maxn];
inline int read(){
int x=0; char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x;
}
void add(int x,int y){son[++tot]=y; nxt[tot]=lnk[x]; lnk[x]=tot;}
bool dfs(int x){
for (int j=lnk[x];j;j=nxt[j])
if (!used[son[j]]){
used[son[j]]=1;
if (!girl[son[j]]||dfs(girl[son[j]])) {girl[son[j]]=x; return 1;}
}
return 0;
}
int main(){
T=read();
while (T--) {
memset(lnk,0,sizeof(lnk)); memset(son,0,sizeof(son)); memset(nxt,0,sizeof(nxt)); memset(girl,0,sizeof(girl)); tot=ans=m=0;
n=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++) b[i]=read();
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++){
int x=read();
if ((i==j||x==1)&&(a[i]==0||b[i]==0)&&a[j]==1) add(i,j);
}
for (int i=1;i<=n;i++) {
if (a[i]==1&&b[i]==1) continue; m++;
memset(used,0,sizeof(used));
if (dfs(i)) ans++;
}
if (ans==m) printf("^_^\n"); else printf("T_T\n");
}
return 0;
}