【BZOJ1433】[ZJOI2009] 假期的宿舍(二分图匹配入门)
大致题意: 有\(n\)个学生,其中一部分是在校学生,一部分不是,而在校学生中一部分回家,一部分不回家,并且我们用一个01矩阵表示学生之间相互认识关系。已知每个学生只能睡自己认识的人的床(当然,他也可以睡自己的床),问是否有一个方案使得所有学生都有床睡。
建图
这道题是一道图论题。对于这种图论题,我们首先要考虑的便是建图。
不难想到,我们可以将每个人与其能睡的床连一条边,即:
- 对于一个在校且不回家的学生\(i\),我们将\(i\)与自己的床连一条边。
- 对于一个在校且不回家或不在校的学生\(i\),如果他认识一个在校的学生\(j\),我们将\(i\)与\(j\)的床连一条边。
之所以上面要强调不回家,是因为对于回家的学生,在给他连边是没有任何意义的。
而这张图建成之后,应该不难发现它是一张二分图,那么原题就变成了一道求二分图最大匹配的题目,就可以用匈牙利算法来解决了。
再看一眼数据范围,\(n≤50\),那么匈牙利算法的\(O(n^2)\)复杂度在这道题目中不是轻松跑跑吗?
代码
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define LL long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define tc() (A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++)
#define N 50
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
char ff[100000],*A=ff,*B=ff;
using namespace std;
int n,m,ee=0,lnk[N+5],vis[N+5],s[N+5],SchoolStudent[N+5],BackHome[N+5];
struct edge
{
int to,nxt;
}e[N*N+5];
inline void read(int &x)
{
x=0;static char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-48,isdigit(ch=tc()));
}
inline bool GetPoint(int x,int t)//为编号为x的点寻找一个匹配
{
register int i;
for(i=lnk[x];i;i=e[i].nxt)//枚举每一个与x相邻的节点
{
if(!(vis[e[i].to]^t)) continue;//如果这个节点已经访问过了,就跳过
vis[e[i].to]=t;//否则,标记这个节点已访问
if(!s[e[i].to]||GetPoint(s[e[i].to],t))//如果这个节点没被匹配,或者与这个节点匹配的节点能找到一个新的节点匹配
{
s[e[i].to]=x;//标记这个节点与x匹配
return true;//找到一个匹配,返回true
}
}
return false;//说明找不到匹配,返回false
}
int main()
{
register int i,j,T,x,ok;read(T);
while(T--)
{
for(read(n),ee=0,ok=i=1;i<=n;++i) vis[i]=s[i]=lnk[i]=0;//多组数据,记得初始化
for(i=1;i<=n;++i) read(SchoolStudent[i]);//读入每个学生是否是在校学生
for(i=1;i<=n;++i) {read(BackHome[i]);if(!SchoolStudent[i]) BackHome[i]=0;}//读入每个学生是否回家,如果不是在校学生,默认其不回家
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
read(x);
if((x&&!BackHome[i]&&SchoolStudent[j])||(i==j&&SchoolStudent[i]&&!BackHome[i])) add(i,j);//如果i认识j,i不回家,且j是在校学生;或者i=j,i是在校学生,且i不回家,将i与j连一条边
}
}
for(i=1;i<=n;++i) if(!BackHome[i]&&!GetPoint(i,i)) {ok=0;break;}//如果某个学生不回家,且找不到床,那么就说明没有使每个人都有床的方案
puts(ok?"^_^":"T_T");
}
return 0;
}
【BZOJ1433】[ZJOI2009] 假期的宿舍(二分图匹配入门)的更多相关文章
- BZOJ1433 ZJOI2009 假期的宿舍 二分图匹配
1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2375 Solved: 1005[Submit][Sta ...
- BZOJ1433 [ZJOI2009]假期的宿舍 二分图匹配 匈牙利算法
原文链接http://www.cnblogs.com/zhouzhendong/p/8372785.html 题目传送门 - BZOJ1433 题解 我们理一理题目. 在校的学生,有自己的床,还可以睡 ...
- [ZJOI2009]假期的宿舍 二分图匹配匈牙利
[ZJOI2009]假期的宿舍 二分图匹配匈牙利 一个人对应一张床,每个人对床可能不止一种选择,可以猜出是二分图匹配. 床只能由本校的学生提供,而需要床的有住校并且本校和外校两种人.最后统计二分图匹配 ...
- [bzoj1433][ZJOI2009]假期的宿舍——二分图
题目大意 传送门 题解 显然是二分图匹配. 用一些方法建图就好了. 要注意的是: 本题有多组数据!!! 初始化一定要注意!!! 代码 #include <bits/stdc++.h> us ...
- P2055 [ZJOI2009]假期的宿舍[二分图匹配]
题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题. 比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识 ...
- BZOJ1433[ZJOI2009]假期的宿舍——二分图最大匹配
题目描述 学校放假了······有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如A 和B都是学校的学生,A要回家,而C来看B,C与A不认识.我们假设每个人只能睡和自己直接认 ...
- bzoj1433: [ZJOI2009]假期的宿舍 [二分图][二分图最大匹配]
Description Input Output Sample Input 1 3 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 Sample Output ˆ ˆ HINT 对于30% ...
- 洛谷 2055 [ZJOI2009]假期的宿舍——二分图匹配
题目:https://www.luogu.org/problemnew/show/P2055 #include<iostream> #include<cstdio> #incl ...
- bzoj1433: [ZJOI2009]假期的宿舍(最大二分图匹配)
1433: [ZJOI2009]假期的宿舍 题目:传送门 题解: 这题有点水 跑个二分图匹配就完事了(注意在校生不是一定都互相认识) 代码: #include<cstdio> #inclu ...
- bzoj1433: [ZJOI2009]假期的宿舍
1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2286 Solved: 969[Submit][Stat ...
随机推荐
- 洛谷P3819 松江1843路
P3819 松江1843路 题目描述 涞坊路是一条长L米的道路,道路上的坐标范围从0到L,路上有N座房子,第i座房子建在坐标为x[i]的地方,其中住了r[i]人. 松江1843路公交车要在这条路上建一 ...
- C 语言实例 - 创建各类三角形图案
C 语言实例 - 创建各类三角形图案 创建三角形图案. 实例 - 使用 * 号 #include <stdio.h> int main() { int i, j, rows; printf ...
- 论js里面的for循环
首先搞懂执行的顺序: 对,执行顺序就是这样的. for循环的作用: 1.在编写代码时,你常常希望反复执行同一段代码. 2.遍历数组,可以用forEach();对于DOM对象(nodelist)的话,比 ...
- Javascript专题(三)b.各种轮播和细节分析--上下滚动轮播
这一次,我们用原生JS实现上下滚动方式的轮播.顺带学习一下用JS来创建HTML元素. 上一次写的轮播是淡入淡出效果的,相对来说其实是比较简单的. github源码: 上下轮播源码-github A. ...
- 关于VS2017提示I/O文件操作函数需要加上_s的解决办法
最近不论是在写网络编程还是在写小项目时候,都会提示让我用加个_s的函数........ 其实加上_s这个函数是为了确保函数的安全性,确保不会有内存不够或者溢出的情况.但是每次都需要重新看一下_s函数的 ...
- 线段树模板(单点更新,区间更新,RMQ)
Bryce1010模板 1.单点更新 说明 单点更新,区间求和(你问我单点求和??你就不会把区间长度设为0啊?) • sum[]为线段树,需要开辟四倍的元素数量的空间. • build()为建树操作 ...
- 02-----body签中相关标签
大纲 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> 排版标 ...
- Win10家庭版打不开gpedit.msc
本文来源 : https://www.ithome.com/html/win10/324926.htm win10家庭版是不自带这个功能的 首先我们打开记事本,并输入以下内容(注意空格): @echo ...
- CSS中的IFC和BFC入门
CSS中的IFC和BFC入门 提到CSS,首先会想到的就是盒模型,如果对于盒模型不是很理解的,看这里.这是一个基础的系列,看了盒模型还可以看看box-sizing,好了不多说了,下面介绍今天的重点 ...
- JavaSE_2_关键字
1.介绍一下Syncronized锁,如果用这个关键字修饰一个静态方法,锁住了什么?如果修饰成员方法,锁住了什么? synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下四种: ...