zoukankan      html  css  js  c++  java
  • 洛谷 P1402 酒店之王

     题目传送门:https://www.luogu.org/problem/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
     

    Solution:

      ~~本题一看就是网络流板子题嘛~~

    一开始看到这题是,二话不说,先构图,超级源点连到房间,房间连接到人,人再连接到饭菜,最后饭菜再连接到超级汇点。结果一交上去,妈耶!WA了7个。看了一遍又一遍代码,就是找不到BUG。莫非,此题有坑?

    随后点开了题解,才知道我是真的菜,网络流根本就没学好。各位用网络流的读者,请注意本题有一个巨坑,请看下这幅图读者就会明白了

                                                    

    一个人只能吃一道菜,住一间房嘛!!!(窝好菜,这么简单的问题都没考虑到QwQ)

    然后,怎么处理呢?

    其实,一人只吃一道菜,住一间房,本质上来说就是一个人只流过一次,我们不难想到,可以个每个人赋上一个流量,拆为两个点,这样没人就只流过一次啦!

    如图:

                                                  

    到此,读者的思路应该也很清晰了,话不多说,上Code:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<queue>
      7 #define R register
      8 #define next kkksc03
      9 using namespace std;
     10 typedef long long ll;
     11 typedef long double ld;
     12 typedef unsigned long long ull;
     13 inline ll read();
     14 ll n,p,q;
     15 ll to[1000000],next[1000000],c[1000000],tot,head[1000000];
     16 inline void add(ll x,ll y,ll z){
     17     to[++tot]=y;c[tot]=z;next[tot]=head[x];head[x]=tot;
     18 }
     19 ll S,T;
     20 ll d[1000000];
     21 queue<ll>Q;
     22 bool bfs(){
     23     memset(d,0,sizeof d);
     24     while(!Q.empty()) Q.pop();
     25     Q.push(S);
     26     d[S]=1;
     27     while(!Q.empty()){
     28         ll x=Q.front();
     29         Q.pop();
     30         for(R ll i=head[x];i;i=next[i]){
     31             ll ver=to[i];
     32             if(!d[ver]&&c[i]){
     33                 d[ver]=d[x]+1;
     34                 Q.push(ver);
     35                 if(ver==T) return true;
     36             }
     37         }
     38     }
     39     return false;
     40 }
     41 ll dinic(ll x,ll flow){
     42     if(x==T||!flow) return flow;
     43     ll k,rest=flow;
     44     for(R ll i=head[x];i&&rest;i=next[i]){
     45         ll ver=to[i];
     46         if(d[ver]==d[x]+1&&c[i]){
     47             k=dinic(ver,min(rest,c[i]));
     48             if(!k) d[ver]=0;
     49             rest-=k;
     50             c[i]-=k;
     51             c[i^1]+=k;
     52         }
     53     }
     54     return flow-rest;
     55 }
     56 int main(){
     57     n=read();p=read();q=read();
     58     S=0;T=n+n+p+q+1;tot=1;
     59     for(R ll i=1;i<=n;i=-~i){
     60         for(R ll j=1,x;j<=p;j=-~j){
     61             x=read();
     62             if(!x) continue;
     63             add(n+j,i,1);
     64             add(i,n+j,0);
     65         }
     66     }
     67     for(R ll i=1;i<=n;i=-~i){
     68         for(R ll j=1,x;j<=q;j=-~j){
     69             x=read();
     70             if(!x) continue;
     71             add(i+p+q+n,n+p+j,1);
     72             add(n+p+j,i+p+q+n,0);
     73         }
     74     }
     75     for(R ll i=1;i<=p;i=-~i){
     76         add(S,n+i,1);
     77         add(n+i,S,0);
     78     }
     79     for(R ll i=1;i<=n;i=-~i){
     80         add(i,n+p+q+i,1);
     81         add(n+p+q+i,i,0);
     82     }
     83     for(R ll i=1;i<=q;i=-~i){
     84         add(n+p+i,T,1);
     85         add(T,n+p+i,0);
     86     }
     87     ll _flow,maxflow=0;
     88     while(bfs()){
     89         while(_flow=dinic(S,0x7fffffff)) maxflow+=_flow;
     90     }
     91     printf("%lld
    ",maxflow);
     92 }
     93 inline ll read(){
     94     ll x=0,t=1;char ch=getchar();
     95     while(ch<'0'||ch>'9'){
     96         if(ch=='-') t=-1;
     97         ch=getchar();
     98     }
     99     while(ch>='0'&&ch<='9'){
    100         x=(x<<1)+(x<<3)+(ch^48);
    101         ch=getchar();
    102     }
    103     return x*t;
    104 }

     

  • 相关阅读:
    c++中,map的使用
    关于C++中vector<vector<int> >的使用
    python中如何向shell脚本传递带空格的参数
    数组初始化及赋值的方法,memset的使用
    leetcode:首个缺少的最小正整数(js实现。)
    安装cmake过程出错:Error when bootstrapping CMake: Cannot find a C++ compiler that supports both C++11 and the specified C++ flags.
    React系列--三大属性 props refs state
    React系列--组件Component
    React系列--jsx语法及虚拟dom,渲染
    c++的复制构造函数,(郑莉 c++语言程序设计)
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/11745558.html
Copyright © 2011-2022 走看看