bzoj1433[ZJOI2009] 假期的宿舍

题目链接: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;
}


posted @ 2017-02-26 21:58  OxQ  阅读(64)  评论(0编辑  收藏