zoukankan      html  css  js  c++  java
  • LuoguP1402 酒店之王

    LuoguP1402 酒店之王

    最大流题目。带有一定的思维技(tao)巧(lu)

    依旧分析题目。如果只有房间或者菜一种限制。那么就是一道裸的最大流了

    可是两种条件都应当满足,

    这貌似也可以做。

    因为每个菜和房间都只能选择一次。我们很容易建出这样一个模型

    As6mh8.md.png

    上图中矩形表示房间,圆表示顾客,三角表示菜

    但是很不幸,是错的

    因为我们忽略了人的限制,每个菜和房间都只能选择一次,每个人也只能被选择一次,即上图中圆圈的点流量不超过(1)

    所以应该将每个圆圈拆成两个点,中间连一条容量为(1)的边,表示人数限制。

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<queue>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int N = 2e5 + 3;
    const int M = 2e6 + 3;
    const int INF = 2e9;
    struct edge{
    	int to;
    	int nxt;
    	int flow;	
    }e[M];
    int n,p,q,s,t,tot = 1;
    int cur[N],head[N],high[N];
    vector <int> G[N];
    inline void add(int x,int y,int z){
    	e[++tot].to = y;
    	e[tot].flow = z;
    	e[tot].nxt = head[x];	
    	head[x] = tot;
    	e[++tot].to = x;
    	e[tot].flow = 0;
    	e[tot].nxt = head[y];
    	head[y] = tot; 
    }
    inline int read(){
        int v = 0,c = 1;char ch = getchar();
        while(!isdigit(ch)){
            if(ch == '-') c = -1;
            ch = getchar();	
        }
        while(isdigit(ch)){
            v = v * 10 + ch - 48;
            ch = getchar();	
        }
        return v * c;
    }
    inline bool bfs(){
    	queue <int> q;
    	for(int i = 0;i <= t;++i) high[i] = 0;
    	q.push(s);high[s] = 1;
    	while(!q.empty()){
    		int k = q.front();q.pop();
    		for(int i = head[k];i;i = e[i].nxt){
    			int y = e[i].to;
    			if(!high[y] && e[i].flow > 0)
    			high[y] = high[k] + 1,q.push(y);
    		}
    	}
    	return high[t] != 0;
    }
    inline int dfs(int x,int dis){
    //	printf("%d %d
    ",x,dis);
    //	system("pause");
    	if(x == t) return dis;
    	for(int &i = cur[x];i;i = e[i].nxt){
    		int y = e[i].to;
    		if(high[y] == high[x] + 1 && e[i].flow > 0){
    			int flow = dfs(y,min(dis,e[i].flow));
    			if(flow > 0){
    				e[i].flow -= flow;
    				e[i ^ 1].flow += flow;
    				return flow;	
    			}
    		}
    	}
    	return 0;
    }
    inline int dinic(){
    	int res = 0;
    	while(bfs()){
    		for(int i = 0;i <= t;++i) cur[i] = head[i];
    		while(int now = dfs(s,INF)) res += now;
    	}
    	return res;
    }
    int main(){
    	n = read(),p = read(),q = read();
    	s = n + n + p + q + 1,t = s + 1;
    	for(int i = 1;i <= n;++i)
    		for(int j = 1;j <= p;++j){
    			int x = read();	
    			if(x) add(j,i + p,1);
    		}
    	for(int i = 1;i <= p;++i) add(s,i,1);
    	for(int i = 1;i <= n;++i) add(i + p,i + p + n,1);
    	for(int i = 1;i <= n;++i)
    		for(int j = 1;j <= q;++j){
    			int x = read();
    			if(x) add(i + p + n,n + n + p + j,1);	
    		}
    	for(int i = 1;i <= q;++i) add(n + n + p + i,t,1);
    	printf("%d
    ",dinic());
    	return 0;	
    }
    
  • 相关阅读:
    每日总结
    团队冲刺9
    团队冲刺8
    团队冲刺7
    团队冲刺6
    团队冲刺5
    团队冲刺4
    团对冲刺3
    团队冲刺2
    每日博客
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/10636640.html
Copyright © 2011-2022 走看看