原题链接

这道题,很明显是个配对问题。于是,我们可以想到用网络最大流来做。

先整理一下题目条件。

  1. 很明显,根据贪心思想,要使最多人满意,每个人应该最多睡一个房间(似乎也没有人能睡两个房间),吃一道菜。这就要求一个人最多与一个房间、一道菜配对。
  2. 每个人必须住进喜欢的房间吃到喜欢的菜才算满意。
  3. 每道菜至多让1个人吃,每个房间至多让1个人睡。

于是,我们得出了建图的几大原则:

  1. 菜与房间分别作为一个点。
  2. 为了保证条件1,每个人应该拆成2个点,并在这两个点之间连一条容量为1的边。
  3. 为了保证条件2,应该让每一个人拆成的第一个点与所有自己喜欢的房间对应的点连一条容量为1的边,让每一个人拆成的第二个点与所有自己喜欢的菜对应的点连一条容量为1的边。
  4. 为了保证条件3,应该让源点\(s\)向所有的房间连一条容量为1的边,所有的菜向汇点\(t\)连一条容量为1的边。

放一张对应的图(样例):

最后EK跑最大流即可。

Code(超级精简,不到60行):

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n,p,q,head[10005],tot=-1,st,ed,flow[10005],pre[10005],maxflow,vis[10005];
  4. const int INF=0x3f3f3f3f;queue<int> qq;
  5. struct Edge{int to,nxt,flow;}e[200005];
  6. void addedge(int x,int y,int f){
  7. e[++tot].to=y;e[tot].nxt=head[x];e[tot].flow=f;head[x]=tot;
  8. e[++tot].to=x;e[tot].nxt=head[y];e[tot].flow=0;head[y]=tot;
  9. }
  10. bool bfs(){
  11. memset(vis,0,sizeof(vis));memset(flow,0,sizeof(flow));flow[st]=INF;
  12. while(!qq.empty()) qq.pop();
  13. qq.push(st);vis[st]=1;
  14. while(!qq.empty()){
  15. int x=qq.front();qq.pop();
  16. for(int i=head[x],y;i!=-1;i=e[i].nxt){
  17. if(e[i].flow>0){
  18. y=e[i].to;
  19. if(vis[y]) continue;
  20. flow[y]=min(flow[x],e[i].flow);pre[y]=i;
  21. vis[y]=1;qq.push(y);
  22. if(y==ed) return 1;
  23. }
  24. }
  25. }
  26. return 0;
  27. }
  28. void doit(){
  29. while(bfs()){
  30. int tmp=ed;maxflow+=flow[ed];
  31. while(tmp!=st){
  32. e[pre[tmp]].flow-=flow[ed],e[pre[tmp]^1].flow+=flow[ed];
  33. tmp=e[pre[tmp]^1].to;
  34. }
  35. }
  36. }
  37. int main(){
  38. memset(head,-1,sizeof(head));
  39. scanf("%d%d%d",&n,&p,&q);
  40. st=0,ed=2*n+p+q+1;
  41. for(int i=1;i<=n;i++){
  42. addedge(i+p,i+n+p,1);
  43. for(int j=1;j<=p;j++){
  44. int x;scanf("%d",&x);
  45. if(x) addedge(j,i+p,1);
  46. }
  47. }
  48. for(int i=1;i<=n;i++){
  49. for(int j=1;j<=q;j++){
  50. int x;scanf("%d",&x);
  51. if(x) addedge(i+p+n,n*2+p+j,1);
  52. }
  53. }
  54. for(int i=1;i<=p;i++) addedge(st,i,1);
  55. for(int i=1;i<=q;i++) addedge(i+n*2+p,ed,1);
  56. doit();printf("%d\n",maxflow);
  57. return 0;
  58. }

【Luogu】P1402 酒店之王 题解的更多相关文章

  1. luogu P1402 酒店之王

    题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜. ...

  2. BZOJ 1711 吃饭dining/Luogu P1402 酒店之王 拆点+最大流流匹配

    题意: (吃饭dining)有F种食物和D种饮料,每种食物或饮料只能供一头牛享用,且每头牛只享用一种食物和一种饮料.现在有n头牛,每头牛都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几头牛同时享 ...

  3. 【luogu P1402 酒店之王】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1402 菜 #include <queue> #include <cstdio> #i ...

  4. 【题解】 Luogu P1402 酒店之王 (二分图匹配)

    懒得复制,原题目戳我 Solution: 这题没想到这么水,就是两个二分图而已 如果房间的二分图没匹配成功就直接进入下一个人 如果房间的二分图匹配成功,食物二分图匹配不成功就把房间的\(be[ ]\) ...

  5. LUOGU P1402 酒店之王 (网络流)

    解题思路 应该比较显然得能看出这是个网络流,将$S$与房间连边,房间与人连边,人与菜连边,菜与汇点连边,边的流量均为1.但这样是错误的,因为有可能一个人跑过去2的流量,所以要将人拆点限流. #incl ...

  6. 洛谷P2891 Dining P1402 酒店之王【类二分图匹配】题解+代码

    洛谷P2891 Dining P1402 酒店之王[类二分图匹配]题解+代码 酒店之王 题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的 ...

  7. P1402 酒店之王【网络流】【最大流】

    P1402 酒店之王 提交 5.39k 通过 2.16k 时间限制 1.00s 内存限制 125.00MB 题目提供者yeszy 难度省选/NOI- 历史分数100 提交记录 查看题解 标签 福建省历 ...

  8. Luogu 1402 酒店之王(二分图最大匹配)

    Luogu 1402 酒店之王(二分图最大匹配) Description XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自 ...

  9. P1402 酒店之王

    P1402 酒店之王 每个人要匹配一个A和一个B,所以这样连边: S向每个房间连边. 每个房间向喜欢这个房间的人连边. 每个人向喜欢的菜连边. 每道菜向T连边. 边权均为1. 注意人要限流. // I ...

随机推荐

  1. DMZ是什么

    刚刚接触安全域,实在是佩服自己真的是菜,,,啥都不懂,看看过段时间能有多大进步吧... 概念 DMZ:它是一个缓冲区,一个隔离区.它是位于两台防火墙之间的区域,相对于INTER网来说安全级别高一些,但 ...

  2. const放在函数前后的区别

    转载:const放在函数前后的区别 一.const修饰指针 int b = 500; 1.const int * a = & b; 2.int const * a = & b; 3.i ...

  3. 使用EasyX和C++写一个消砖块游戏

    第一次玩EasyX,写一个比较简单的消砖块游戏. 主函数包括Game的类的开始,运行和结束. 1 #include "BrickElimination.h" 2 3 int mai ...

  4. 【题解】[国家集训队]happiness

    题目戳我 \(\text{Solution:}\) 显然还是一个分组问题.对于理科和文科我们可以看出最小割模型,而处理同时选择某一学科的时候,需要我们根据套路建立虚点处理. 同 小M的作物 一题,这题 ...

  5. 【原创】经验分享:一个小小emoji尽然牵扯出来这么多东西?

    前言 之前也分享过很多工作中踩坑的经验: 一个线上问题的思考:Eureka注册中心集群如何实现客户端请求负载及故障转移? [原创]经验分享:一个Content-Length引发的血案(almost.. ...

  6. Git命令diff格式详解

    diff是Unix系统的一个很重要的工具程序. 它用来比较两个文本文件的差异,是代码版本管理的基石之一.你在命令行下,输入: $ diff <变动前的文件> <变动后的文件> ...

  7. Python 疑难问题:[] 与 list() 哪个快?为什么快?快多少呢?

    本文出自"Python为什么"系列,请查看全部文章 在日常使用 Python 时,我们经常需要创建一个列表,相信大家都很熟练了吧? # 方法一:使用成对的方括号语法 list_a ...

  8. 多测师全方位面试题腾讯 _自动化面试题_高级讲师肖sir

    作答注意:候选人可以两题都做,也可以两题任选一题做即可. 笔试题一:1.查询 https://www.newsmth.net/nForum/#!board/PieLove2.获取发贴时间是2020年8 ...

  9. C#中的SqlBulkCopy批量插入数据

    在C#中,我们可以使用sqlBulkCopy去批量插入数据,其他批量插入方法不在讨论. 1 /// <summary> 2 /// SqlBulkCopy批量插入数据 3 /// < ...

  10. Pytest学习(一)- 入门及基础

    前言 十一也赶上自己刚出院,本想在十一放假前用假期刷完Pytest的,结果被希洛克神话吸引,再次回归毒奶粉,一直奋斗到距离上班还有两天,引导石刷没了,就没了智慧. 当然也没出过神话,结果一怒之下卸载, ...