zoukankan      html  css  js  c++  java
  • luogu P1402 酒店之王 |网络流最大匹配

    题目描述

    XX 酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化。由于很多来住店的旅客有自己喜好的房间色调、阳光等,也有自己所爱的菜,但是该酒店只有 (p) 间房间,一天只有固定的 (q) 道不同的菜,每个房间只能住一位客人,每道菜也只能给一位客人食用。

    有一天来了 (n) 个客人,每个客人说出了自己喜欢哪些房间,喜欢哪道菜。但是很不幸,可能做不到让所有顾客满意(满意的条件是住进喜欢的房间且吃到喜欢的菜)。

    要怎么分配,能使最多顾客满意呢?

    输入格式

    第一行给出三个整数,分别表示表示 (n,p,q)

    之后 (n) 行,每行 (p) 个整数,只可能是 (0)(1),第 (i) 行第 (j) 个数表示第 (i) 个人喜不喜欢第 (j) 个房间((1) 表示喜欢, (0) 表示不喜欢)。

    之后 (n) 行,每行 (q) 个整数,只可能是 (0)(1),第 (i) 行第 (j) 个数表示第 (i) 个人喜不喜欢第 (j) 道菜((1) 表示喜欢, (0) 表示不喜欢)。

    输出格式

    最大的顾客满意数。


    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int N=5e4+5,M=1e6+5,inf=1<<30;
    int nxt[M],head[N],go[M],edge[M],tot=1;
    inline void add(int u,int v,int w){
        nxt[++tot]=head[u],head[u]=tot,go[tot]=v,edge[tot]=w;
        nxt[++tot]=head[v],head[v]=tot,go[tot]=u,edge[tot]=0;
    }
    int n,p,q,now[N];
    int s,t,d[N],maxflow;
    bool bfs(){
        queue<int>q;
        memset(d,0,sizeof(d));
        q.push(s); d[s]=1;
        now[s]=head[s];
        while(q.size()){
            int u=q.front(); q.pop();
            for(int i=head[u];i;i=nxt[i]){
                int v=go[i];
                if(edge[i]&&!d[v]){
                    q.push(v);
                    d[v]=d[u]+1;
                    now[v]=head[v];
                    if(v==t)return 1;
                }
            }
        }
        return 0;
    }
    int dinic(int u,int flow){
        if(u==t)return flow;
        for(int &i=now[u];i;i=nxt[i]){
            int v=go[i];
            if(edge[i]&&d[v]==d[u]+1){
                int k=dinic(v,min(flow,edge[i]));
                if(!k)d[v]=0;
                else{
                    edge[i]-=k;
                    edge[i^1]+=k;
                    return k;
                }
            }
        }
        return 0;
    }
    signed main(){
        cin>>n>>p>>q;
        s=n+n+p+q+2,t=n+n+p+q+1;
        for(int i=1;i<=p;i++)add(s,i,1);
        
        for(int i=1,x;i<=n;i++)
        for(int j=1;j<=p;j++){
            scanf("%d",&x);
            if(x)add(j,i+p,1);
        }
        for(int i=1;i<=n;i++)add(i+p,i+p+n,1);
        for(int i=1,x;i<=n;i++)
        for(int j=1;j<=q;j++){
            scanf("%d",&x);
            if(x)add(i+p+n,i+p+n+n,1);
        }
        for(int j=1;j<=q;j++)add(p+n+n+j,t,1);
        int flow=0;
        while(bfs())
        while(flow=dinic(s,inf))maxflow+=flow;
        cout<<maxflow<<endl;
    }
    
  • 相关阅读:
    第72届奥斯卡最佳动画奖《老人与海》
    关不掉的手机应用程序
    李嘉诚:知识并不一定使你的财富增加
    Linux之父Linus Torvalds谈软件开发管理经验
    Google 正式发布Dart编程语言
    代码本身其实并不重要,重要的是用户
    22个基于HTML5开发的网站
    看看耶鲁大学心态 ,送给正在奋斗的人 !
    用 git 维护 vim 代码
    谈程序语言的设计及程序员心态
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/12922155.html
Copyright © 2011-2022 走看看