P1402 酒店之王

漂亮小姐姐点击就送:https://www.luogu.org/problemnew/show/P1402

 

题目描述

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

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

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

输入输出格式

输入格式:

第一行给出三个正整数表示n,p,q(<=100)。

之后n行,每行p个数包含0或1,第i个数表示喜不喜欢第i个房间(1表示喜欢,0表示不喜欢)。

之后n行,每行q个数,表示喜不喜欢第i道菜。

输出格式:

最大的顾客满意数。

输入输出样例

输入样例#1: 复制
2 2 2
1 0
1 0
1 1
1 1
输出样例#1: 复制
1


// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;

const int N=1e4+5;
const int M=3e4+5;
const int INF=0x7fffffff;

int n,p,q,S,T;
int head[N],num_edge;
struct Edge
{
    int v,flow,nxt;
}edge[M<<1];

inline int read()
{
    char c=getchar();int num=0,f=1;
    for(;!isdigit(c);c=getchar())
        f=c=='-'?-1:f;
    for(;isdigit(c);c=getchar())
        num=num*10+c-'0';
    return num*f;
}

inline void add_edge(int u,int v,int flow)
{
    edge[++num_edge].v=v;
    edge[num_edge].flow=flow;
    edge[num_edge].nxt=head[u];
    head[u]=num_edge;
}

int dep[N];
inline bool bfs()
{
    memset(dep,0,sizeof(dep));
    queue<int> que;
    que.push(S),dep[S]=1;
    int now,v;
    while(!que.empty())
    {
        now=que.front(),que.pop();
        for(int i=head[now];i;i=edge[i].nxt)
        {
            if(edge[i].flow)
            {
                v=edge[i].v;
                if(dep[v])
                    continue;
                dep[v]=dep[now]+1;
                if(v==T)
                    return 1;
                que.push(v);
            }
        }
    }
    return 0;
}

int dfs(int now,int flow)
{
    if(now==T)
        return flow;
    int outflow=0,tmp,v;
    for(int i=head[now];i;i=edge[i].nxt)
    {
        if(edge[i].flow)
        {
            v=edge[i].v;
            if(dep[v]!=dep[now]+1)
                continue;
            tmp=dfs(v,min(flow,edge[i].flow));
            if(tmp)
            {
                outflow+=tmp;
                flow-=tmp;
                edge[i].flow-=tmp;
                edge[i^1].flow+=tmp;
                if(!flow)
                    return outflow;
            }
        }
    }
    dep[now]=0;
    return outflow;
}

int main()
{
    num_edge=1;
    n=read(),p=read(),q=read();
    T=p+q+n*2+1;
    for(int i=1;i<=n;++i)
    {
        add_edge(i+p,i+p+n,1);
        add_edge(i+p+n,i+p,0);
    }
    for(int i=1;i<=p;++i)
    {
        add_edge(S,i,1);
        add_edge(i,S,0);
    }
    for(int i=1;i<=q;++i)
    {
        add_edge(i+p+2*n,T,1);
        add_edge(T,i+p+n*2,0);
    }
    for(int i=1,a;i<=n;++i)
    {
        for(int j=1;j<=p;++j)
        {
            a=read();
            if(a)
            {
                add_edge(j,i+p,1);
                add_edge(i+p,j,0);
            }
        }
    }
    for(int i=1,a;i<=n;++i)
    {
        for(int j=1;j<=q;++j)
        {
            a=read();
            if(a)
            {
                add_edge(i+p+n,j+p+n*2,1);
                add_edge(j+p+n*2,i+p+n,0);
            }
        }
    }
    int flow=0;
    while(bfs())
        flow+=dfs(S,INF);
    printf("%d",flow);
    return 0;
}
原文地址:https://www.cnblogs.com/lovewhy/p/8665907.html