ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[洛谷P1402]酒店之王

2019-01-31 17:03:07  阅读:249  来源: 互联网

标签:连边 洛谷 每道菜 P1402 房间 之王 int maxn include


题目大意:有$n$个人,$p$个房间,$q$道菜($n,p,q\leqslant100$),每个人有自己喜欢的房间和菜,问最多使得多少个人高兴(即拥有喜欢的房间和菜)

题解:网络流,源点向每道菜连边,每道菜向喜欢的人连边,每个人向喜欢的房间连边,每个房间再向汇点连边。发现这样人会重复,于是把人拆点即可。

卡点:

 

C++ Code:

#include <algorithm>
#include <cstdio>
#include <iostream>
#define maxn 111
const int N = maxn << 2, M = maxn * maxn * 2 + maxn * 3;
const int inf = 0x3f3f3f3f;

namespace Network_Flow {
	int lst[N], head[N], cnt = 1;
	struct Edge {
		int to, nxt, w;
	} e[M << 1];
	inline void addedge(int a, int b, int c = 1) {
		e[++cnt] = (Edge) { b, head[a], c }; head[a] = cnt;
		e[++cnt] = (Edge) { a, head[b], 0 }; head[b] = cnt;
	}

	int n, st, ed, MF;
	int GAP[N], d[N];
	int q[N], h, t;

	void init() {
		GAP[d[ed] = 1] = 1;
		for (int i = st; i <= ed; ++i) lst[i] = head[i];
		q[h = t = 0] = ed;
		while (h <= t) {
			int u = q[h++];
			for (int i = head[u]; i; i = e[i].nxt) {
				int v = e[i].to;
				if (!d[v]) {
					d[v] = d[u] + 1;
					++GAP[d[v]];
					q[++t] = v;
				}
			}
		}
	}
	int dfs(int u, int low) {
		if (!low || u == ed) return low;
		int w, res = 0;
		for (int &i = lst[u]; i; i = e[i].nxt) if (e[i].w) {
			int v = e[i].to;
			if (d[u] == d[v] + 1) {
				w = dfs(v, std::min(low, e[i].w));
				res += w, low -= w;
				e[i].w -= w, e[i ^ 1].w += w;
				if (!low) return res;
			}
		}
		if (!(--GAP[d[u]])) d[st] = n + 1;
		++GAP[++d[u]], lst[u] = head[u];
		return res;
	}
	void ISAP(int S, int T) {
		st = S, ed = T;
		n = ed - st + 1;
		init();
		while (d[st] <= n) MF += dfs(st, inf);
	}
}
using Network_Flow::addedge;

int n, p, q;
int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
	std::cin >> n >> p >> q;
	int st = 0, ed = p + q + n + n + 1;
	for (int i = 1; i <= p; ++i) addedge(st, i);
	for (int i = 1, t; i <= n; ++i) {
		for (int j = 1; j <= p; ++j) {
			std::cin >> t;
			if (t) addedge(j, i + p);
		}
	}
	for (int i = 1; i <= n; ++i) addedge(i + p, i + n + p);
	for (int i = 1, t; i <= n; ++i) {
		for (int j = 1; j <= q; ++j) {
			std::cin >> t;
			if (t) addedge(i + n + p, j + n + n + p);
		}
	}
	for (int i = 1; i <= p; ++i) addedge(i + n + n + p, ed);
	Network_Flow::ISAP(st, ed);
	std::cout << Network_Flow::MF << std::endl;
	return 0;
}

  

标签:连边,洛谷,每道菜,P1402,房间,之王,int,maxn,include
来源: https://www.cnblogs.com/Memory-of-winter/p/10342645.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有