Description
Input
Output
Sample Input
1
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0
Sample Output
ˆ_ˆ
HINT
对于30% 的数据满足1 ≤ n ≤ 12。
对于100% 的数据满足1 ≤ n ≤ 50,1 ≤ T ≤ 20。
把人视为左边的集合,把床视为右边的集合,跑一遍最大匹配。
连边的时候思路要清晰。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int t,n,x,now,tot;
int a[55][55],p[55],mark[55],xy[55];
int head[55],Next[2505],to[2505];
void add(int x,int y)
{
tot++;
Next[tot]=head[x];
to[tot]=y;
head[x]=tot;
}
int dfs(int k)
{
for(int i=head[k];i!=-1;i=Next[i])
if(mark[to[i]]!=now)
{
mark[to[i]]=now;
if(xy[to[i]]==-1||dfs(xy[to[i]]))
{
xy[to[i]]=k;
return 1;
}
}
return 0;
}
int match()
{
int res=0;
for(int i=1;i<=n;i++) xy[i]=-1;
for(int i=1;i<=n;i++)
if(p[i]!=2)
{
now++;
if(dfs(i)) res++; else return 0;
}
return 1;
}
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&p[i]);//student
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(p[i]==1)
{
if(x==1) p[i]=2; //back
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) scanf("%d",&a[i][j]);
tot=0;
for(int i=1;i<=n;i++) head[i]=-1;
for(int i=1;i<=n;i++)
if(p[i]!=2)
{
if(p[i]==1) add(i,i); //in school
for(int j=1;j<=n;j++)
if(a[i][j]==1&&p[j]>0) add(i,j);
}
if(match()) printf("%c%c%c\n",94,95,94);
else printf("%c%c%c\n",84,95,84);
}
return 0;
}