LUOGU P1402 酒店之王 (网络流)

解题思路

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

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>

using namespace std;
const int MAXN = 505;
const int MAXM = 50005;
const int inf = 0x3f3f3f3f;

inline int rd(){
    int x=0;char ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();}
    return x;
}

int n,p,q,head[MAXN],cnt=1,to[MAXM<<1],nxt[MAXM<<1],val[MAXM<<1];
int ans,S,T=500,d[MAXN];
queue<int> Q;

inline void add(int bg,int ed,int w){
    to[++cnt]=ed,nxt[cnt]=head[bg],val[cnt]=w,head[bg]=cnt;
}

inline bool bfs(){
    while(Q.size()) Q.pop();
    memset(d,0,sizeof(d));d[S]=1;Q.push(S);
    while(Q.size()){
        int x=Q.front();Q.pop();
        for(register int i=head[x];i;i=nxt[i]){
            int u=to[i];
            if(!d[u] && val[i]){
                d[u]=d[x]+1;
                Q.push(u);
                if(u==T) return true;
            }
        }
    }
    return false;
}

int dinic(int x,int flow){
    if(x==T) return flow;
    int res=flow,k;
    for(register int i=head[x];i && res;i=nxt[i]){
        int u=to[i];
        if(d[u]==d[x]+1 && val[i]){
            k=dinic(u,min(val[i],flow));
            if(!k) d[u]=0;
            val[i]-=k;val[i^1]+=k;res-=k;
        }
    }
    return flow-res;
}

int main(){
    n=rd(),p=rd(),q=rd();int x;
    for(int i=1;i<=p;i++) add(S,i,1),add(i,S,0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=p;j++){
            x=rd();if(!x) continue;
            add(j,i+p,1),add(i+p,j,0);
        }
    for(int i=1;i<=n;i++) add(i+p,i+p+n,1),add(i+p+n,i+p,0);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=q;j++){
            x=rd();if(!x) continue;
            add(i+p+n,j+n*2+p,1),add(j+n*2+p,i+p+n,0);
        }
    for(int i=1;i<=q;i++) add(i+n*2+p,T,1),add(T,i+n*2+p,0);
    while(bfs()) ans+=dinic(S,inf);
    cout<<ans;
    return 0;
}

原文地址:https://www.cnblogs.com/sdfzsyq/p/9784582.html

时间: 2024-11-13 09:40:41

LUOGU P1402 酒店之王 (网络流)的相关文章

luogu P1402 酒店之王

题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜. 有一天来了n个客人,每个客人说出了自己喜欢哪些房间,喜欢哪道菜.但是很不幸,可能做不到让所有顾客满意(满意的条件是住进喜欢的房间,吃到喜欢的菜). 这里要怎么分配,能使最多顾客满意呢? 输入输出格式 输入格式: 第一行给出三个正整数表示n,p,q(<=100). 之后n行,每行p个数包含0或1,第

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

P1402 酒店之王 题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜. 有一天来了n个客人,每个客人说出了自己喜欢哪些房间,喜欢哪道菜.但是很不幸,可能做不到让所有顾客满意(满意的条件是住进喜欢的房间,吃到喜欢的菜). 这里要怎么分配,能使最多顾客满意呢? 输入输出格式 输入格式: 第一行给出三个正整数表示n,p,q(<=100). 之后n行,每

[洛谷 P1402] 酒店之王

题目描述 Description XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜.有一天来了n个客人,每个客人说出了自己喜欢哪些房间,喜欢哪道菜.但是很不幸,可能做不到让所有顾客满意(满意的条件是住进喜欢的房间,吃到喜欢的菜).这里要怎么分配,能使最多顾客满意呢? 输入输出格式 Input/output 输入格式:第一行给出三个正整数表示n,p,q(<=1

P1402 酒店之王 最大流

\(\color{#0066ff}{ 题目描述 }\) XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜. 有一天来了n个客人,每个客人说出了自己喜欢哪些房间,喜欢哪道菜.但是很不幸,可能做不到让所有顾客满意(满意的条件是住进喜欢的房间,吃到喜欢的菜). 这里要怎么分配,能使最多顾客满意呢? $\color{#0066ff}{ 输入格式 } $ 第一行给出三

P1402 酒店之王

感觉这就是一道蓝题,并不算紫题,但是这道题的思想很重要. 记得我做过的第一道网络流,用到的就是这个思想,就是拆点. 因为我们要防止中间的点被用到多次啊-- 别问我为什么,因为我不会再一次解释那是因为只有边才有容量,点没有容量,一个点只要入流等于出流,无论有多少条边经过它,都是可以的. 那么我们可以把中间点拆开,再连一条边权为1的边即可. 注意:每个点的标号特备容易弄混-- 代码: #include<cstdio> #include<iostream> #include<cst

luogu 1402 酒店之王

最大流模版题,注意都是将点转换成边.再跑模版即可. #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<queue> using namespace std; const int maxn=1010,inf=9999999; struct node{ int to,w,rev; }; int iter[maxn],level[maxn

「LuoguP1402」 酒店之王(最大流

题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜. 有一天来了n个客人,每个客人说出了自己喜欢哪些房间,喜欢哪道菜.但是很不幸,可能做不到让所有顾客满意(满意的条件是住进喜欢的房间,吃到喜欢的菜). 这里要怎么分配,能使最多顾客满意呢? 输入输出格式 输入格式: 第一行给出三个正整数表示n,p,q(<=100). 之后n行,每行p个数包含0或1,第

酒店之王

酒店之王 题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜. 有一天来了n个客人,每个客人说出了自己喜欢哪些房间,喜欢哪道菜.但是很不幸,可能做不到让所有顾客满意(满意的条件是住进喜欢的房间,吃到喜欢的菜). 这里要怎么分配,能使最多顾客满意呢? 输入输出格式 输入格式: 第一行给出三个正整数表示n,p,q(<=100). 之后n行,每行p个数包含

luoguP1402 酒店之王

为了练dinic优化,再写一道网络流 原题链接: https://www.luogu.org/problemnew/show/P1402 写了很多非常辣鸡的代码还觉得挺对的我... 题意简述:有n个顾客,m道菜,q个房间,顾客满意的条件是能吃到自己喜欢的菜,住自己满意的房间,求最多能让多少顾客满意. 首先建边,源点连向所有的菜,菜向喜欢这道菜的顾客连一条边,顾客向他喜欢的房间连一条边,跑最大流即可. 然而这是错的. 为什么?假设有这个情况,一位顾客同时喜欢多个房间,但是很显然,他最多只能住一个房