P2055 [ZJOI2009]假期的宿舍【二分图/最大流】
题目描述
学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题。
比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识。我们假设每个人只能睡和自己直接认识的人的床。那么一个解决方案就是 B 睡 A 的床而 C 睡 B 的床。而实际情况可能非常复杂,有的人可能认识好多在校学生,在校学生之间也不一定都互相认识。
我们已知一共有 n 个人,并且知道其中每个人是不是本校学生,也知道每个本校学生是否回家。问是否存在一个方案使得所有不回家的本校学生和来看他们的其他人都有地方住。
输入格式
第一行一个数 T 表示数据组数。接下来 T 组数据,每组数据第一行一个数n 表示涉及到的总人数。
接下来一行 n 个数,第 i 个数表示第 i 个人是否是在校学生 (0 表示不是,1 表示是)。再接下来一行 n 个数,第 i 个数表示第 i 个人是否回家 (0 表示不回家,1 表示回家,注意如果第 i 个人不是在校学生,那么这个位置上的数是一个随机的数,你应该在读入以后忽略它)。
接下来 n 行每行 n 个数,第 i 行第 j 个数表示 i 和 j 是否认识 (1 表示认识,0 表示不认识,第 i 行 i 个的值为 0,但是显然自己还是可以睡自己的床),认识的关系是相互的。
输出格式
对于每组数据,如果存在一个方案则输出 “^_^”(不含引号) 否则输出“T_T”(不含引号)。(注意输出的都是半角字符,即三个符号的 ASCII 码分别为94,84,95)
输入输出样例
1
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0
^_^
说明/提示
对于 30% 的数据满足 1 ≤ n ≤ 12。
对于 100% 的数据满足 1 ≤ n ≤ 50,1 ≤ T ≤ 20。
多组数据!!!
思路
把人和床位分成两个不同的点集来看,要求最大的匹配数量问是否等于 留校人数 + 外来人员数量。
显然跑最大流和二分匹配都是可以的。
CODE
#include <bits/stdc++.h> using namespace std;
const int maxn = ; int n,m,e, tot, sum;
int vis[maxn];
int ask[maxn];
int ans;
int inschool[maxn];
int matched[maxn];
int gohome[maxn];
int head[], edge[], nxt[], cnt; void BuildGraph(int u, int v) {
cnt++;
edge[cnt] = v;
nxt[cnt] = head[u];
head[u] = cnt;
} bool fid(int x) {
for(int i = head[x]; i; i = nxt[i]) {
int v = edge[i];
if(!vis[v]) {
vis[v] = ;
if(!matched[v] || fid(matched[v])) {
matched[v] = x;
return true;
}
}
}
return false;
} void match() {
sum = ;
memset(matched, , sizeof(matched));
for(int i = ; i <= n; ++i) {
if((inschool[i] && !gohome[i]) || !inschool[i]) {
memset(vis, , sizeof(vis));
if(fid(i)) {
sum++;
}
}
}
} int main()
{ int t;
cin >> t;
while(t--) {
scanf("%d",&n);
cnt = , tot = , sum = ;
memset(edge, , sizeof(edge));
memset(vis, , sizeof(vis));
memset(head, , sizeof(head));
memset(inschool, , sizeof(inschool));
memset(gohome, , sizeof(gohome));
memset(nxt, , sizeof(nxt));
for ( int i = ; i <= n; ++i ) {
scanf("%d",&inschool[i]);
}
for ( int i = ; i <= n; ++i ) {
scanf("%d",&gohome[i]);
if(!gohome[i] && inschool[i]) {
BuildGraph(i, i);
}
}
for ( int i = ; i <= n; ++i ) {
if(!inschool[i] || (inschool[i] && !gohome[i])) {
++tot;
}
}
for ( int i = ; i <= n; ++i ) {
for ( int j = ; j <= n; ++j ) {
int x;
scanf("%d",&x);
if(x && inschool[j]) {
BuildGraph(i, j);
}
}
}
match();
if(tot == sum) puts("^_^");
else {
puts("T_T");
}
//printf("tot:%d sum:%d\n",tot,sum);
}
return ;
}
P2055 [ZJOI2009]假期的宿舍【二分图/最大流】的更多相关文章
- P2055 [ZJOI2009]假期的宿舍[二分图匹配]
题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题. 比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识 ...
- 洛谷P2055 [ZJOI2009]假期的宿舍 [二分图最大匹配]
题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识. ...
- P2055 [ZJOI2009]假期的宿舍 题解(二分图)
题目链接 P2055 [ZJOI2009]假期的宿舍 解题思路 因为懒,提供一种不连边,直接根据题目给出的邻接矩阵进行匈牙利算法的思路. \(a[i][j]\)表示\(i\)能不能睡\(j\)的床,需 ...
- 洛谷P2055 [ZJOI2009]假期的宿舍
P2055 [ZJOI2009]假期的宿舍 题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A ...
- 洛谷——P2055 [ZJOI2009]假期的宿舍
P2055 [ZJOI2009]假期的宿舍 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 ...
- [ZJOI2009]假期的宿舍 二分图匹配匈牙利
[ZJOI2009]假期的宿舍 二分图匹配匈牙利 一个人对应一张床,每个人对床可能不止一种选择,可以猜出是二分图匹配. 床只能由本校的学生提供,而需要床的有住校并且本校和外校两种人.最后统计二分图匹配 ...
- BZOJ1433 ZJOI2009 假期的宿舍 二分图匹配
1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2375 Solved: 1005[Submit][Sta ...
- bzoj1433 [ZJOI2009]假期的宿舍(最大流)
1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1717 Solved: 754[Submit][Stat ...
- 洛谷$P2055\ [ZJOI2009]$ 假期的宿舍 最大流
正解:最大流 解题报告: 传送门$QwQ$ 这种一看就很网络流鸭,直接说咋建图趴. 考虑把在校的人拆成人和床.$S$连向所有不回家的人,所有床连向$T$,认识的人之间人向床连边,跑个最大流就成. $o ...
随机推荐
- Java并发编程(二):volatile关键字
volatile是Java虚拟机提供的轻量级的同步机制.volatile关键字有如下两个作用,一句话概括就是内存可见性和禁止重排序. 1)保证被volatile修饰的共享变量对所有线程总是可见的,也就 ...
- 聊聊CMDB的前世今生
CMDB,Configuration Management DataBase,配置管理数据库,是与 IT 系统所有组件相关的信息库,它包含 IT 基础架构配置项的详细信息. 传统运维思路下的CMDB, ...
- qt QSplitter分割窗口
#include <QApplication> #include <QFont> #include <QTextEdit> #include <QSplitt ...
- Java.work6 stasic、this、包总结作业20194651
题目一: 编写一个类Computer,类中含有一个求n的阶乘的方法.将该类打包,并在另一包中德Java文件App.java中引入包,在主类中定义Computer类的对象,调用求n的阶乘的方法(n值由参 ...
- shell命令之一天一见:awk
AWK是一种优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一. 这种编程及数据操作语言(其名称得自于它的创始人阿尔佛雷德·艾侯.彼得·溫伯格和布萊恩·柯林漢姓氏的首个字 ...
- error C2338: No Q_OBJECT in the class with the signal (NodeCreator.cpp)
在Qt中,当派生类需要用到信号与槽机制时,有两个要求. 1.该类派生自QObject类. 2.类中有Q_OBJECT宏. 本次报错的原因就是因为没有在类中添加Q_OBJECT宏. 而我的出错原因更傻逼 ...
- PPT导出图片质量太差?简单操作直接导出印刷质地图片
PPT导出图片质量太差?简单操作直接导出印刷质地图片 PPT不仅可以用于展示文档,还可以用于简单图片合成处理,同时,PPT文档还可以全部导出为图片. 默认情况下,PPT导出的图片为96DPI ...
- 消息队列MQ集合
消息队列MQ集合 消息队列简介 kafka简介 Centos7部署zookeeper和Kafka集群 .
- linux中的正则表达式知识梳理
1. 正则表达式 1.1 正则表达式使用 正则表达式是开发者为了处理大量的字符串和文本而定义的一套规则和方法,使用正则表达式可以提高效率,快速获取想要的内容. 正则表达式常用于linux三剑客grep ...
- 利用django打造自己的工作流平台(三):团队成员任务跟踪系统
近期受疫情影响公司食堂不开放,为解决同事们的吃饭问题,部门需要在每周五统计下周的订餐情况:员工根据个人意愿选择是否从公司订下周的午餐和晚餐,一旦确定一周保持不变. 通常要完成一次部门内员工的订餐信息收 ...