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];
vector<node>map[maxn];
void add_edge(int s,int t,int w){
    map[s].push_back((node){t,w,map[t].size()});
    map[t].push_back((node){s,0,map[s].size()-1});
}
void bfs(int s){
    memset(level,-1,sizeof(level));
    queue<int>q;
    level[s]=0;
    q.push(s);
    while(!q.empty()){
        int v=q.front();
        q.pop();
        for(int i=0;i<map[v].size();++i){
            if(level[map[v][i].to]<0&&map[v][i].w>0){
                level[map[v][i].to]=level[v]+1;
                q.push(map[v][i].to);
            }
        }
    }
}
int dfs(int s,int t,int k){
    if(s==t){
        return k;
    }
    for(int &i=iter[s];i<map[s].size();++i){
        node &edge=map[s][i];
        if(edge.w>0&&level[edge.to]>level[s]){
            int d=dfs(edge.to,t,min(k,edge.w));
            if(d>0){
                edge.w-=d;
                map[edge.to][edge.rev].w+=d;
                return d;
            }
        }
    }
    return -1;
}
int max_flow(int s,int t){
    int ret=0;
    for(;;){
        bfs(s);
        if(level[t]<0)break;
        memset(iter,0,sizeof(iter));
        while(1){
            int d=dfs(s,t,inf);
            if(d<=0)break;
            ret+=d;
        }
    }
    return ret;
}
int main(){
    int s,t;
    int n,p,q;
    cin>>n>>p>>q;
    s=2*n+2*p+2*q+1;
    t=2*n+2*p+2*q+2;
    for(int i=2;i<=2*n+2*p+2*q;i+=2){
        add_edge(i,i-1,1);
        if(i-1>2*n&&i-1<2*n+2*p){
            add_edge(i-1,t,1);
        }
        if(i>2*n+2*p){
            add_edge(s,i,1);
        }
    }

    for(int i=1;i<=n;++i){
        for(int j=1;j<=p;++j){
            bool b;
            cin>>b;
            if(b)
            add_edge(i*2-1,2*j+2*n,1);
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=q;++j){
            bool b;
            cin>>b;
            if(b)
            add_edge(2*p+2*n+j*2-1,i*2,1);
        }
    }
    cout<<max_flow(s,t);
    return 0;

}
时间: 2024-10-14 07:29:19

luogu 1402 酒店之王的相关文章

luogu P1402 酒店之王

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

LUOGU P1402 酒店之王 (网络流)

解题思路 应该比较显然得能看出这是个网络流,将$S$与房间连边,房间与人连边,人与菜连边,菜与汇点连边,边的流量均为1.但这样是错误的,因为有可能一个人跑过去2的流量,所以要将人拆点限流. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<queue> using namespace std;

酒店之王

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

[洛谷 P1402] 酒店之王

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

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

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

「LuoguP1402」 酒店之王(最大流

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

P1402 酒店之王 最大流

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

luoguP1402 酒店之王

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

P1402 酒店之王

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