zoukankan      html  css  js  c++  java
  • [洛谷P1402]酒店之王

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

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

    卡点:

    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;
    }
    

      

  • 相关阅读:
    vbox安装增强功能,实现宿主机文件夹共享并浏览器访问
    linux镜像下载
    linux命令之sed
    关于MySQL数据库的备份方案
    linux防火墙使用以及配置
    Jenkins安装部署(二)
    Jenkins安装部署(一)
    Centos7在虚拟机中扩展磁盘空间
    CentOS 7系统根目录分区扩容
    Linux下的SVN服务器搭建
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10342645.html
Copyright © 2011-2022 走看看