[ZJOI2009]假期的宿舍

题目:洛谷P2055、BZOJ1433、codevs2347。

题目大意:有n个人,有些人是学生,有些人是来看学生的(不是学生)。学生有床,而非学生没有(废话!)。有些学生回家,有些学生晚上住校,来看学生的人要住在学校里。

现在有一些认识的关系,规定每个要在学校睡觉的人只会睡在自己认识的人的床上,问能否使所有人都有床睡?

解题思路:人匹配床,很明显是二分图匹配。

先把住校的学生和自己的床连边,然后把所有要睡在学校的人和他认识的人的床(如果有)连边。

然后匈牙利乱搞即可。

C++ Code:

#include<cstdio>
#include<cctype>
#include<cstring>
int n,dy[55];
bool b[55][55],vis[55];
struct xingxi{
	int zs,hj;
}a[55];
int dfs(int u){
	for(int v=1;v<=n;++v)
	if(!vis[v]&&b[u][v]){
		vis[v]=true;
		if(!dy[v]||dfs(dy[v])){
			dy[v]=u;
			return 1;
		}
	}
	return 0;
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		memset(b,0,sizeof b);
		for(int i=1;i<=n;++i)
		scanf("%d",&a[i].zs);
		int bed=n;
		for(int i=1;i<=n;++i){
			scanf("%d",&a[i].hj);
			if(!a[i].zs)a[i].hj=0;
			else
			if(!a[i].hj)b[i][i]=true;
			bed-=a[i].hj;
		}
		for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j){
			int f;
			scanf("%d",&f);
			if(f&&!a[i].hj&&a[j].zs)b[i][j]=true;
		}
		int match=0;
		memset(dy,0,sizeof dy);
		for(int i=1;i<=n;++i)
		if(!a[i].hj){
			memset(vis,0,sizeof vis);
			match+=dfs(i);
		}
		if(match==bed)
		puts("^_^");else
		puts("T_T");
	}
	return 0;
}

 

posted @ 2017-10-19 16:04  Mrsrz  阅读(200)  评论(0编辑  收藏  举报