传送门:>Here<

题意:有N个人去酒店,酒店共有P个房间,Q道菜。已知每个人喜欢特定的几个房间和几道菜,一个人是满意的当且仅当住了喜欢的房间,吃了喜欢的菜(一个人只能选一个房间一道菜)。问最多有多少人是满意的

思路分析

利用最大流来解。这题看上去有点像二分图匹配,然而并不是“二分图”。显然只要我们建好图然后跑Dinic即可

如何建图呢?最初的一个想法是容量全部为1,每个人连向源点,再分别连向每道菜,再连向每个房间。然而一看样例跑出来就不对……

首先我们考虑到是人去选择,所以房间和菜肯定都是连人的,因此不能像刚才那样菜去连房间。

考虑把人放在中间,源点先连房间,房间连人,人连菜,菜再连到汇点

貌似没有什么问题?如果一共只有一个人,这个人喜欢三种菜和三种房间,那么按照这种做法答案会跑出来3。震惊,一个人竟然跑出来3!

其实问题就出在对最大流的理解上——最大流仅仅只有对管道容量的约束,并没有对每一个点能容纳多少有约束。在这道题里,一个人最多只能选择一个房间和一道菜,因此有必要把每一个人所能够得到的约束为1。这个其实也很好想,只需要把人拆开,每个人连一条容量为1的边到他的附身,这样即使前面的自己得到了多个匹配,经过后面的这一条管道也就只能流过1了,完美地解决了问题

Code

/*By DennyQi*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define  r  read()
#define  Max(a,b)  (((a)>(b)) ? (a) : (b))
#define  Min(a,b)  (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int MAXN = 2010;
const int MAXM = 100010;
const int INF = 1061109567;
inline int read(){int x = 0; int w = 1; register int c = getchar();while(c ^ '-' && (c < '0' || c > '9')) c = getchar();if(c == '-') w = -1, c = getchar();while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar(); return x * w;
}
int N,P,Q,S,T,x;
int first[MAXM*2],nxt[MAXM*2],to[MAXM*2],cap[MAXM*2],flow[MAXM*2],num_edge=-1;
int level[MAXN],cur[MAXN];
queue <int> q;
inline void add(int u, int v, int c, int f){to[++num_edge] = v;cap[num_edge] = c;flow[num_edge] = f;nxt[num_edge] = first[u];first[u] = num_edge;
}
inline bool BFS(){memset(level, 0, sizeof(level));while(!q.empty()) q.pop();q.push(S);level[S] = 1;int u,v;while(!q.empty()){u = q.front(); q.pop();for(int i = first[u]; i != -1; i = nxt[i]){v = to[i];if(!level[v] && cap[i]-flow[i] > 0){level[v] = level[u] + 1;q.push(v);}}}return level[T]!=0;
}
int DFS(int u, int a){if(u == T || a == 0) return a;int ans = 0,v,_f;for(int& i = cur[u]; i != -1; i = nxt[i]){v = to[i];if(level[u]+1==level[v] && cap[i]-flow[i] > 0){_f = DFS(v, Min(a, cap[i]-flow[i]));ans += _f, a -= _f;flow[i] += _f, flow[i^1] -= _f;if(a == 0) break;}}return ans;
}
inline void Dinic(){int ans = 0;while(BFS()){for(int i = S; i <= T; ++i) cur[i] = first[i];ans += DFS(S, INF);}printf("%d", ans);
}
int main(){N=r,P=r,Q=r;S=0, T = 2*N+P+Q+2;memset(first, -1, sizeof(first));for(int i = 1; i <= P; ++i){add(S, i+2*N, 1, 0);add(i+2*N, S, 0, 0);}for(int i = 1; i <= N; ++i){for(int j = 1; j <= P; ++j){x=r;if(x){add(j+2*N, i, 1, 0);add(i, j+2*N, 0, 0);}}}for(int i = 1; i <= N; ++i){add(i, i+N, 1, 0);add(i+N, i, 0, 0);}for(int i = 1; i <= N; ++i){for(int j = 1; j <= Q; ++j){x=r;if(x){add(i+N, j+P+2*N, 1, 0);add(j+P+2*N, i+N, 0, 0);}}}for(int i = 1; i <= Q; ++i){add(P+2*N+i, T, 1, 0);add(T, P+2*N+i, 0, 0);}Dinic();return 0;
}

转载于:https://www.cnblogs.com/qixingzhi/p/9417804.html

洛谷P1402 酒店之王相关推荐

  1. 洛谷 P1402 酒店之王

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

  2. 洛谷P1402 酒店之王(二分图)

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

  3. [洛谷P1402] 酒店之王

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

  4. 洛谷P1402 酒店之王--网络流最大流拆点

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

  5. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  6. 洛谷 P1142 轰炸

    洛谷 P1142 轰炸 题目描述 "我该怎么办?"飞行员klux向你求助. 事实上,klux面对的是一个很简单的问题,但是他实在太菜了. klux要想轰炸某个区域内的一些地方,它们 ...

  7. 洛谷 P1387 最大正方形

    P1387 最大正方形 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=10 ...

  8. 洛谷P2763 试题库问题

    题目:https://www.luogu.org/problemnew/show/P2763 题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性. ...

  9. 动态规划——洛谷_P1057传球游戏

    题目: 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏.游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球, ...

最新文章

  1. python运维实战--跨堡垒机连接二级服务器上传文件
  2. Windows Azure平台Win VM密码重置
  3. 用bat实现自启动程序
  4. Windows程序设计:MFC 、Winform 和 WPF 比较
  5. 面试官:Maven 的这 7 个问题你思考过没有?
  6. OpenCV applyColorMap函数实现False color伪色彩的实例(附完整代码)
  7. c#通过app.manifest使程序以管理员身份运行
  8. 扫地机器人单扫和双扫_小米扫拖机器人体验:再见了,拖把君
  9. PostgreSQL 10 自定义并行计算聚合函数的原理与实践
  10. 20145209 《信息安全系统设计基础》课程总结
  11. @开发者 想成为行业应用开发的实力派吗?TA 或者能帮到你
  12. iOS 11 将于9月19日正式发布,一文带你了解它的那些特性
  13. 面试必问的 Linux 命令帮你整理好啦 (下)
  14. Visual Studio 11预览:DirectX和SharePoint特性
  15. js得到自定义属性和操作table表格
  16. Oracle 11g 服务名称以及作用
  17. VS 2013安装教程
  18. MindManager带你走进三顾茅庐
  19. bzoj-1270 [BeijingWc2008]雷涛的小猫
  20. urp教务系统简单利用

热门文章

  1. if vue 跳出_vue实现弹框遮罩点击其他区域弹框关闭及v-if与v-show的区别介绍
  2. python找出最小数_找出不除N的最小数
  3. 力扣 根据数字二进制下1的数目排序
  4. 公司没有与员工签订劳动合同,也没有给员工购买社保,现在员工被公司解雇,该如何要求赔偿?
  5. 哪些事情瞬间暴露了你的贫穷?
  6. 今天突然领悟到,想要赚钱必须先放平心态
  7. 某电子工厂老板感叹创业开厂人生
  8. 几种可以不用过于投入精力去交往的人脉
  9. Js判断是否在微信浏览器中打开和微信版本号
  10. python信道仿真_Hanlp在Python环境中安装及使用.md