BZOJ1433

二分图匹配。

把人和床分在图两边,若床存在(在校学生),人与该床的主人有关系,就可以连边。

要注意自己可以匹配自己的床!

回家的人就不需要床了!!空出一张床

#include<cstdio>
#include<cstdlib>
#include<cstring>
bool bed[51];
bool home[51];
bool map[51][51];
int p[51][51];
int mat[51];
bool vis[51];
int n;
bool dfs(int x)
{
for (int i=1;i<=n;i++)
{
if (p[x][i]==true)
{
if (vis[i]==false)
{
vis[i]=true;
if (mat[i]==-1||dfs(mat[i])==true)
{
mat[i]=x;
return true;
}
}
}
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int need=0;
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&bed[i]);
for (int i=1;i<=n;i++)
{
scanf("%d",&home[i]);
if (bed[i]==0||(bed[i]==1&&home[i]==0))
need++;
}
memset(p,false,sizeof(p));
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
bool o;
scanf("%d",&o);
if (bed[j]==true&&o==true&&(bed[i]==1&&home[i]==0||bed[i]==0))
p[i][j]=true;
}
if (bed[i]==true&&home[i]==false)
p[i][i]=true;
}
int num=0;
memset(mat,-1,sizeof(mat));
for (int i=1;i<=n;i++)
{
memset(vis,false,sizeof(vis));
if (dfs(i)==true)
num++;
}
if (num>=need)
printf("^_^\n");
else
printf("T_T\n");
}
}

posted on 2016-11-09 13:49  Notok  阅读(69)  评论(0编辑  收藏

导航

统计