题目:洛谷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; }