【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 ...
随机推荐
- 清北刷题冲刺 10-30 a.m
星空 #include<iostream> #include<cstdio> using namespace std; int n,m; int main(){ freopen ...
- mui 从子页面返回至父页面,同时刷新父页面
今天在写页面的时候,有一个需求,就是新闻列表项的时候,会显示出浏览次数,点击进入页面的时候,也会有浏览次数,且浏览次数比点击之前的已经+1了.那么用户返回到新闻列表页的时候,浏览次数应该更新了. mu ...
- android 拖拽图片&拖动浮动按钮到处跑
来自老外: 拖拽图片效果 方法一: 布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLa ...
- [转][iOS Crash文件分析]-如何使用symbolicatecrash工具
上传一软件,被拒了,自己测试了n遍都未出现这个情况,今天用symbolicatecrash工具分析了一下苹果提供的Crash文件,最终查到是 - (void)mapView:(MKMapView *) ...
- [题解](线段树最大连续子段和)POJ_3667_Hotel
题意:1.求一个最靠左的长x的区间全部为0,并修改为1,输出这个区间的左端点 2.修改一个区间为0 实际上是维护最大连续子段和,原来也写过 大概需要维护一个左/右最大子段和,当前这段最大子段长,再维护 ...
- atom快捷键
文件切换 ctrl-shift-s 保存所有打开的文件 cmd-shift-o 打开目录 cmd-\ 显示或隐藏目录树 ctrl-0 焦点移到目录树 目录树下,使用a,m,delete来增加,修改和删 ...
- vuex和localStorage/sessionStorage 区别
1.最重要的区别:vuex存储在内存,localstorage则以文件的方式存储在本地 2.应用场景:vuex用于组件之间的传值,(响应式的),localstorage则主要用于不同页面之间的传值(其 ...
- python基本数据类型练习
一.元素分类# 有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中.# 即 ...
- 【ACM】取石子 - 博弈论
取石子(一) 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 一天,TT在寝室闲着无聊,和同寝的人玩起了取石子游戏,而由于条件有限,他/她们是用旺仔小馒头当作石子.游 ...
- HDU 5877 Weak Pair DFS + 树状数组 + 其实不用离散化
http://acm.hdu.edu.cn/listproblem.php?vol=49 给定一颗树,然后对于每一个节点,找到它的任何一个祖先u,如果num[u] * num[v] <= k.则 ...