学校放假了······有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题。比如A和B都是学校的学生,A要回家,而C来看B,C与A不认识。我们假设每个人只能睡和自己直接认识的人的床。那么一个解决方案就是B睡A的床而C睡B的床。而实际情况可能非常复杂,有的人可能认识好多在校学生,在校学生之间也不一定都互相认识。我们已知一共有n个人,并且知道其中每个人是不是本校学生,也知道每个本校学生是否回家。问是否存在一个方案使得所有不回家的本校学生和来看他们的其他人都有地方住。
二分图匹配大水题,“公牛”就为除了回家的本校学生之外的人,”母牛”就为除了不在校学生之外的人,之后再仔细判断是否能匹配就可以了。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
int n,belong[55];
bool v[55],vv[55],mp[55][55],chw[55];
bool find_muniu(int x)
{
for(int i=1;i<=n;i++)
{
if(v[i]==true && mp[x][i]==true && chw[i]==true)
{
chw[i]=false;
if(belong[i]==0 || find_muniu(belong[i])==true)
{
belong[i]=x;
return true;
}
}
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(mp,false,sizeof(mp));
memset(vv,true,sizeof(vv));
memset(belong,0,sizeof(belong));
int wy=0,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
if(x==1)v[i]=true;
else v[i]=false;
}
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
if(v[i]==true)
{
if(x==0)mp[i][i]=true;
else wy++,vv[i]=false;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int x;
scanf("%d",&x);
if(x==1)
{
if(v[i]==true)mp[j][i]=true;
if(v[j]==true)mp[i][j]=true;
}
}
}
for(int i=1;i<=n;i++)
{
if(vv[i]==true)
{
memset(chw,true,sizeof(chw));
if(find_muniu(i)==true)ans++;
else break;
}
}
if(ans==n-wy)printf("^_^\n");
else printf("T_T\n");
}
return 0;
}