• 酒店之王


    酒店之王

    题目描述

    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

    题解:
    裸的最大流,只不过人要拆成两个点,用以保证每一个人只用一次。
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<ctime>
    using namespace std;
    int n,m,l;
    struct node
    {
        int next,to,cap;
    }edge[300001];
    int size=1,head[501];
    void putin(int from,int to,int cap)
    {
        size++;
        edge[size].next=head[from];
        edge[size].cap=cap;
        edge[size].to=to;
        head[from]=size;
    }
    void in(int from,int to,int cap)
    {
        putin(from,to,cap);
        putin(to,from,0);
    }
    int dist[501],numbs[501];
    void bfs(int src,int des)
    {
        int i;
        queue<int>mem;
        mem.push(des);
        numbs[0]++;
        while(!mem.empty())
        {
            int x=mem.front();mem.pop();
            for(i=head[x];i!=-1;i=edge[i].next)
            {
                int y=edge[i].to;
                if(edge[i].cap==0&&dist[y]==0&&y!=des)
                {
                    dist[y]=dist[x]+1;
                    numbs[dist[y]]++;
                    mem.push(y);
                }
            }
        }
        return;
    }
    int dfs(int src,int flow,int des)
    {
        if(src==des)return flow;
        int i,low=0,mindist=n+n+m+l+2;
        for(i=head[src];i!=-1;i=edge[i].next)
        {
            int y=edge[i].to;
            if(edge[i].cap)
            {
                if(dist[y]==dist[src]-1)
                {
                    int t=dfs(y,min(flow-low,edge[i].cap),des);
                    edge[i].cap-=t;
                    edge[i^1].cap+=t;
                    low+=t;
                    if(dist[src]>=n+n+m+l+2)return low;
                    if(low==flow)break;
                }
                mindist=min(mindist,dist[y]+1);
            }
        }
        if(!low)
        {
            if(!(--numbs[dist[src]]))dist[n+n+m+l+2]=n+n+m+l+2;
            ++numbs[dist[src]=mindist];
        }
        return low;
    }
    int ISAP(int src,int des)
    {
        int ans=0;
        bfs(src,des);
        while(dist[0]<n+n+m+l+2)ans+=dfs(src,2e8,des);
        return ans;
    }
    int main() 
    {
        int i,j;
        memset(head,-1,sizeof(head));
        scanf("%d%d%d",&n,&m,&l);
        for(i=1;i<=m;i++)in(0,i,1);
        for(i=m+n+n+1;i<=m+n+n+l;i++)in(i,n+n+m+l+1,1);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                int k;
                scanf("%d",&k);
                if(k)in(j,m+i,1);
            }
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=l;j++)
            {
                int k;
                scanf("%d",&k);
                if(k)in(m+n+i,m+n+n+j,1);
            }
        }
        for(i=m+1;i<=m+n;i++)
        {
            in(i,i+n,1);
        }
        printf("%d",ISAP(0,n+n+m+l+1));
        return 0;
    }
  • 相关阅读:
    Solo 博客系统 1.7.0 发布
    <Android 基础(二十九)> Fragment (2) ~ DialogFragment
    2016最新Java学习计划
    <Android 基础(二十八)> Fragment (1)
    2016最新前端学习计划
    Android 学习路线图
    C/C++学习路线图
    小学数学题,你会吗?
    劣质代码评析——《写给大家看的C语言书(第2版)》附录B之21点程序(八)
    劣质代码评析——《写给大家看的C语言书(第2版)》》附录B之21点程序(七)
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/6885888.html
Copyright © 2020-2023  润新知