P2055 [ZJOI2009]假期的宿舍[二分图匹配]
题目描述
学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题。
比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识。我们假设每个人只能睡和自己直接认识的人的床。那么一个解决方案就是 B 睡 A 的床而 C 睡 B 的床。而实际情况可能非常复杂,有的人可能认识好多在校学生,在校学生之间也不一定都互相认识。
我们已知一共有 n 个人,并且知道其中每个人是不是本校学生,也知道每个本校学生是否回家。问是否存在一个方案使得所有不回家的本校学生和来看他们的其他人都有地方住。
解析
看一眼,哦吼,二分图最大匹配没得跑了。
显然留在学校没走的人(包括在校学生和外来人)都要与一张床匹配,而在校学生(包括走了的)都有床。那么我们可以把所有在学校的人当作左部节点,把所有床当作右部节点,如果最大匹配\(=\)留在学校的学生人数,该方案可行。
匈牙利或者最大流,我写的最大流,练练手。
参考代码
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define N 51
#define M 10010
#define INF 0x3f3f3f3f
using namespace std;
inline int read()
{
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct rec{
int next,ver,leng;
}g[M<<1];
int head[M],tot,d[M],n,num;
int is[N],home[N];
inline void add(int x,int y,int val)
{
g[++tot].ver=y,g[tot].leng=val;
g[tot].next=head[x],head[x]=tot;
}
inline bool bfs()
{
memset(d,0,sizeof(d));
queue<int> q;
d[0]=1;q.push(0);
while(q.size()){
int x=q.front();q.pop();
for(int i=head[x];i;i=g[i].next){
int y=g[i].ver,z=g[i].leng;
if(!z||d[y]) continue;
d[y]=d[x]+1;
q.push(y);
if(y==n*2+1) return 1;
}
}
return 0;
}
inline int dinic(int x,int flow)
{
if(x==n*2+1) return flow;
int rest=flow;
for(int i=head[x];i;i=g[i].next){
int y=g[i].ver,z=g[i].leng;
if(!z||d[y]!=d[x]+1) continue;
int k=dinic(y,min(rest,z));
if(!k) d[y]=0;
else{
g[i].leng-=k;
g[i^1].leng+=k;
rest-=k;
}
}
return flow-rest;
}
int main()
{
int T;
T=read();
while(T--){
memset(head,0,sizeof(head));
memset(is,0,sizeof(is));//在校学生为 1
memset(home,0,sizeof(home));//回家的人为 1
tot=1,num=0;
n=read();
for(int i=1;i<=n;++i){
is[i]=read();
if(is[i]) add(i+n,n*2+1,1),add(n*2+1,i+n,0);
}
for(int i=1;i<=n;++i){
home[i]=read();
if(!home[i]||!is[i]) add(0,i,1),add(i,0,0),num++;
}
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j){
int x=read();
if(j>i) continue;
if(i==j&&!home[i]) add(i,i+n,1),add(i+n,i,0);
else if(x) add(i,j+n,1),add(j+n,i,0),add(j,i+n,1),add(i+n,j,0);
}
int now,ans=0;
while(bfs())
while((now=dinic(0,INF))) ans+=now;
if(ans==num) printf("^_^\n");
else printf("T_T\n");
}
return 0;
}
P2055 [ZJOI2009]假期的宿舍[二分图匹配]的更多相关文章
- [ZJOI2009]假期的宿舍 二分图匹配匈牙利
[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 题解 我们理一理题目. 在校的学生,有自己的床,还可以睡 ...
- 洛谷P2055 [ZJOI2009]假期的宿舍 [二分图最大匹配]
题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识. ...
- 洛谷 2055 [ZJOI2009]假期的宿舍——二分图匹配
题目:https://www.luogu.org/problemnew/show/P2055 #include<iostream> #include<cstdio> #incl ...
- P2055 [ZJOI2009]假期的宿舍 题解(二分图)
题目链接 P2055 [ZJOI2009]假期的宿舍 解题思路 因为懒,提供一种不连边,直接根据题目给出的邻接矩阵进行匈牙利算法的思路. \(a[i][j]\)表示\(i\)能不能睡\(j\)的床,需 ...
- 洛谷P2055 [ZJOI2009]假期的宿舍
P2055 [ZJOI2009]假期的宿舍 题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A ...
- 洛谷——P2055 [ZJOI2009]假期的宿舍
P2055 [ZJOI2009]假期的宿舍 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 ...
- 洛谷 P2055 [ ZJOI 2009 ] 假期的宿舍 —— 二分图匹配
题目:https://www.luogu.org/problemnew/show/P2055 二分图匹配: 注意要连边的话对方必须有床! 代码如下: #include<iostream> ...
随机推荐
- 第2/7Beta冲刺
1.团队成员 成员姓名 成员学号 秦裕航 201731062432(组长) 刘东 201731062227 张旭 201731062129 王伟 201731062214 2.SCRU部分 2.1各成 ...
- 通过LxRunOffline迁移Win10的Linux子系统
默认情况WSL装在系统盘(C:),重装系统怎么办?C盘空间不足怎么办?能修改WSL安装路径吗? 当然可以,使用LxRunOffline不仅能修改WSL安装路径,还能备份WSL.还原WSL…… 修改WS ...
- dubbo学习之路-SPI机制
dubbo学习之路-SPI机制 1.SPI 1.1Java SPI 原理 SPI是service provider interface简称.在java JDK中 内置的一种服务提供发现机制.它解决在一 ...
- 【C++札记】指针数组和数组指针
指针数组: 存储指针的数组,数组找那个的每个一元素都是指针 例: int* p1[4],p2[0]是一个指向int类型的指针 char* p2[4],p1[0]是一个指向char类型的指针 数组指针: ...
- 你应该掌握linux中Bash命令的一些快捷方式
在本文中,我们将分享许多对任何Linux用户都有用的Bash命令行快捷方式.这些快捷方式可以快速地执行某些动作,例如访问和运行先前执行的命令,打开编辑器,在命令行上编辑/删除/更改文本,移动光标,控制 ...
- vue中指令绑定的v-if逻辑结构
<!-- if判断 --> <div id="app2"> <p v-if="seen"> <!-- 给p标签绑定指令 ...
- 接口标记为@ResponseBody却不进入ResponseBodyAdvice
一.背景: 我们的接口为了统一,在ResponseBodyAdvice中对返回值做统一处理,默认添加了errorNo和errorInfo字段返回. 最近同事改接口代码的时候,发现接口返回值是空的.乍一 ...
- Linux 用户管理命令笔记
1.新增用户 useradd user1 用户创建流程 1.系统先将用户信息记录在/etc/passwd中,一般会在/etc/passwd和/etc/shadow末尾,同时分配该用户UID. 2.创建 ...
- Window 服务器安装MongoDB 设置外网可访问
1.下载MongoDB www.mongodb.com/download-center#community 2.下一步下一步安装. 安装完成后配置环境变量 我的的默认安装,环境变量地址 C:\Pro ...
- 安装Ubuntu18.04系统
一.安装Ubuntu系统 进入系统安装的第一个界面,开始系统的安装操作.每一步的操作,左下角都会提示操作方式!! 1.选择系统语言-English 2.键盘设置-English 3.选择操作Insta ...