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;
    }
    
  • 相关阅读:
    Linux中的官方源、镜像源汇总
    提示"libc.so.6: version `GLIBC_2.14' not found"
    win8.1 安装msi软件出现 2503、2502
    平均负载(Load average)
    oracle 导入报错:field in data file exceeds maximum length
    一个命令的输出作为另外一个命令的输入
    Http 状态码
    Linux 命令总结
    ORA-12505: TNS: 监听程序当前无法识别连接描述符中所给出的SID等错误解决方法
    轻松应对IDC机房带宽突然暴涨问题
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/12922155.html
Copyright © 2011-2022 走看看