题目链接:bzoj1433
题目大意:
T组数据,n个人。有些人是学校里的学生,他们在学校里就有床位。但其中有人走读,所以他们的床位到了晚上就会空出来。而有些人晚上会来拜访学校里的人,但他们没有床位。假设每个人只能睡跟他直接认识的人的床,问有没有一种分床的方案使晚上在学校的每个人都有床睡。
题解:
匈牙利求二分图最大匹配
以在校睡的人和床连边构二分图。跑最大匹配。判断一下是不是完美匹配就好了。
我只能说输出真恶心!WA了我两次QwQ样例在欺骗我!
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 110
struct node
{
int x,y,next;
}a[maxn*maxn];int len,first[maxn];
int no[maxn],stu[maxn];
int bf[maxn],ask[maxn],tim;
void ins(int x,int y)
{
len++;a[len].x=x;a[len].y=y;
a[len].next=first[x];first[x]=len;
}
bool ffind(int x)
{
for (int i=first[x];i!=-1;i=a[i].next)
{
int y=a[i].y;
if (ask[y]==tim) continue;
ask[y]=tim;
if (bf[y]==-1 || ffind(bf[y]))
{
bf[y]=x;
return true;
}
}
return false;
}
int main()
{
int T,i,n,x,sm,num,j,ans;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
num=sm=ans=tim=0;
for (i=1;i<=n;i++)
{
scanf("%d",&x);
if (x==0) no[i]=-1;
else no[i]=++num;
}
for (i=1;i<=n;i++)
{
scanf("%d",&x);
if (no[i]==-1) stu[i]=++sm;
else if (x==0) stu[i]=++sm;
else stu[i]=-1;
}
len=0;memset(first,-1,sizeof(first));
for (i=1;i<=n;i++) if (stu[i]!=-1 && no[i]!=-1) ins(stu[i],no[i]);
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
scanf("%d",&x);
if (x==1 && stu[i]!=-1 && no[j]!=-1) ins(stu[i],no[j]);
}
memset(bf,-1,sizeof(bf));
memset(ask,0,sizeof(ask));
for (i=1;i<=n;i++)
if (stu[i]!=-1)
{
tim++;
if (ffind(stu[i])) ans++;
}
if (ans==sm) printf("^_^\n");
else printf("T_T\n");
}
return 0;
}