我们可以把点分为两类
一类是要♂床♂睡的,一类是提供床的(话说不就是个床铺问题么?两个人睡一张床也没问题的吧(啊!好大~)!如果B看A但是性别不同怎么办?这题问题太多了!)
貌似又扯到奇怪的事情上去了23333
然后跑个二分图匹配就好了,正好试试匈牙利算法~
样例所对应的图
AC-Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int maxn=75;
vector<int> v[maxn];
typedef vector<int>::iterator it;
int bed[maxn],need[maxn],mat[maxn],use[maxn],n,totneed;
void reset()
{
for (int i=1;i<maxn;i++)
v[i].clear();
memset(bed,0,sizeof(bed));
memset(need,0,sizeof(need));
memset(mat,0,sizeof(mat));
memset(use,0,sizeof(use));
n=totneed=0;
}
int find(int x)
{
for (it i=v[x].begin();i!=v[x].end();i++)
{
if (!use[*i]&&bed[*i])
{
use[*i]=1;
if (mat[*i]==0||find(mat[*i]))
{
mat[*i]=x;
return 1;
}
}
}
return 0;
}
int xyl()
{
int match=0;
for (int i=1;i<=n;i++)
{
if (!need[i])
{
memset(use,0,sizeof(use));
match+=find(i);
}
}
return match;
}
void work()
{
reset();
int t;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&need[i]);
bed[i]=need[i];
}
for (int i=1;i<=n;i++)
{
scanf("%d",&t);
if (bed[i]&&!t)
need[i]=0;
if (!need[i])
totneed++;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
{
scanf("%d",&t);
if (t||(i==j))
v[i].push_back(j);
}
if (xyl()==totneed)
printf("^_^\n");
else
printf("T_T\n");
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
work();
return 0;
}