版权声明:欢迎转载欢迎评论! https://blog.csdn.net/rabbit_ZAR/article/details/85240633
题目:假期的宿舍
emm……
为什么二分图会写错这么多次?
我不会说是因为我建图建错了的……
思路:
我好像没有说过我建错了图,二分图匹配好像没有什么好说的,所以这里说下建图的问题。
首先,我们考虑用学生和空床匹配。
床的个数一定等于本校学生人数,因为不管学生是否离校,他们的床都在。
需要和床匹配的人数就是 没有回家的本校学生人数 + 非本校学生。
所以,一个人 i 可以和 j的床 连边的条件,当且仅当 j 是本校学生,且i是 没有回家的本校学生人数 或本校学生。
然后在这张图上跑二分图模板就好了。
用最大流或者匈牙利随便啦,这里给出匈牙利代码。
代码:
#include<bits/stdc++.h>
using namespace std;
#define read(x) scanf("%d",&x)
#define maxn 50
int n;
int sc[maxn+5],hm[maxn+5];
vector<int> a[maxn+5]; //i -> bedlist
int mth[maxn+5];
bool use[maxn+5];
bool dfs(int x) {
if(use[x]) return false;
use[x]=true;
for(int i=0;i<a[x].size();i++) {
int y=a[x][i];
if((!mth[y])||dfs(mth[y])) {
mth[y]=x;
return 1;
}
}
return 0;
}
int main() {
int T;
read(T);
while(T--) {
int n;
read(n);
for(int i=1; i<=n; i++) a[i].clear();
memset(mth,0,sizeof(mth));
for(int i=1; i<=n; i++) read(sc[i]);
for(int i=1; i<=n; i++) read(hm[i]);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
int z;
read(z);
if(sc[i]&&hm[i]) continue;
if(!sc[j]) continue;
if(!z) continue;
a[i].push_back(j);
}
for(int i=1;i<=n;i++) if(sc[i]&&!hm[i]) a[i].push_back(i);
int cnt=n;
for(int i=1; i<=n; i++) if(sc[i]&&hm[i]) cnt--;
int ans=0;
for(int i=1; i<=n; i++) {
memset(use,0,sizeof(use));
if(dfs(i)) ans++;
}
if(ans==cnt) printf("^_^");
else printf("T_T");
printf("\n");
}
return 0;
}