Loading

P2055 [ZJOI2009]假期的宿舍 题解(二分图)

题目链接

P2055 [ZJOI2009]假期的宿舍

解题思路

因为懒,提供一种不连边,直接根据题目给出的邻接矩阵进行匈牙利算法的思路。

\(a[i][j]\)表示\(i\)能不能睡\(j\)的床,需要根据具体情况在读入的时候适当调整。

\(inv[i]\)表示第\(i\)个需要在学校睡觉的人(可能是在校学生也可能是校外人员)

AC代码

#include<stdio.h>
#include<string.h>
int a[60][60],is[60],leave[60],vis[60],mt[60];
//a[i][j]:i能不能睡j的床 
int inv[60],cnt,n;
//inv[i]:第i个要在学校睡觉的人 
int dfs(int p,int t){
	int i;
	for(i=1;i<=n;i++){
		if(a[inv[p]][i]&&vis[i]!=t){
			vis[i]=t;
			if(!mt[i]||dfs(mt[i],t))return mt[i]=p;
		}
	}
	return 0;
}
int main(){
	int i,j,t;
	scanf("%d",&t);
	while(t--){
		int ans=0;cnt=0;
		memset(vis,0,sizeof(vis));
		memset(mt,0,sizeof(mt));
		scanf("%d",&n);
		for(i=1;i<=n;i++)
			scanf("%d",&is[i]);
		for(i=1;i<=n;i++){
			scanf("%d",&leave[i]);
			if(!is[i]||!leave[i])inv[++cnt]=i;
			//如果这人不是学校的或者不回家那就要在学校睡觉 
		}
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++){
				scanf("%d",&a[i][j]);
				if(i==j&&is[i]&&!leave[i])a[i][j]=1;
				//如果在校没回家那可以睡自己的床 
				if(!is[j])a[i][j]=0;
				//如果不是学校的没床可以给别人睡 
			}
		for(i=1;i<=cnt;i++)
			if(dfs(i,i))ans++;
			else break;
		if(ans!=cnt)printf("T_T\n");
		else printf("^_^\n");
	}
	return 0;
}
posted @ 2019-02-26 17:22  Potassium  阅读(139)  评论(0编辑  收藏  举报