Luogu1402.酒店之王

mean
\(\quad\)告诉你有\(n\)个客人,\(p\)个房间和\(q\)道菜,每个客人喜欢一些房间和一些菜,每个房间和菜只可以服务与一个客人,求最多能使客人满意的数量有多少。

idea
\(\quad\)我们考虑使用网络流来解决这道题目,分别把客人,房间,菜品看做节点,然后用超级源点连接所有房间,用超级汇点连接所有菜品,然后在按题目要求分别连接房间与人和人与菜品,但是我们会发现一个问题,就是我们无法保证一个客人只选择一套,所以我们考虑把代表人的节点割开,一个节点连接房间,一个节点连接菜品,两个点之间用容量为1的管道连接起来。这样就处理好了这个问题,然后直接跑最大流就可以了。记得注意数组大小!

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<climits>
#include<sstream>
using namespace std;
#include<vector>
#include<queue>

inline int read()
{
  char c ; int flag = 1;
  while((c = getchar()) < '0' || c > '9'){if(c == '-'){flag = -1;}}
  int count = c - '0';
  while((c = getchar()) >= '0' && c <= '9'){count *= 10 ; count += c - '0';}
  return count * flag;
}
inline void print(int x)
{
  if(x < 0){x = -x ; putchar('-');}
  if(x > 9){print(x / 10);}
  putchar(x % 10 + '0');
}

const int N = 510;
const int M = 1e5 + 10;

int head[N] , net[M] , vis[M] , wigh[M] ; int tot = 1;
int book[N][N];
inline void add(int u , int v , int w){tot++ ; net[tot] = head[u] ; head[u] = tot ; vis[tot] = v ; wigh[tot] = w;}

int dep[N] ; int t;
queue<int> q;
inline bool bfs()
{
  memset(dep , 0 , sizeof(dep));
  dep[0] = 1 ; q.push(0);
  while(!q.empty())
  {
    int u = q.front() ; q.pop();
    for(register int i = head[u] ; i ; i = net[i])
    {
      int v = vis[i] , w = wigh[i] ; if(dep[v] != 0 || w == 0){continue;}
      dep[v] = dep[u] + 1;
      q.push(v);
    }
  }
  return dep[t];
}

int dfs(int u , int in)
{
  if(u == t){return in;} int out = 0;
  for(register int i = head[u] ; i ; i = net[i])
  {
    int v = vis[i] , w = wigh[i] ; if(dep[v] != dep[u] + 1 || w == 0){continue;}
    int res = dfs(v , min(in , w));
    wigh[i] -= res;
    wigh[i ^ 1] += res;
    in -= res;
    out += res;
  }
  if(out == 0){return dep[u] = 0;}
  else{return out;}
}

vector<int> f[N];
int main()
{
  int n = read() , p = read() , q = read();
  for(register int i = 1 ; i <= p ; i++)
  {
    add(0 , i , 1);
    add(i , 0 , 0);
  }
  for(register int i = 1 ; i <= q ; i++)
  {
    add(p + n + n + i , p + n + n + q + 1 , 1);
    add(p + n + n + q + 1 , p + n + n + i , 0);
  }
  for(register int i = 1 ; i <= n ; i++)
  {
    add(p + i , p + n + i , 1);
    add(p + n + i , p + i , 0);
  }
  for(register int i = 1 ; i <= n ; i++)
  {
    for(register int j = 1 ; j <= p ; j++)
    {
      if(read())
      {
        add(j , p + i , 1);
        add(p + i , j , 0);
      }
    }
  }
  for(register int i = 1 ; i <= n ; i++)
  {
    for(register int j = 1 ; j <= q ; j++)
    {
      if(read())
      {
        add(p + n + i , p + n + n + j , 1);
        add(p + n + n + j , p + n + i , 0);
      }
    }
  }
  int ans = 0 ; t = p + n + n + q + 1;
  while(bfs()){ans += dfs(0 , 1e9);}
  print(ans);
  return 0;
}
posted @ 2020-11-01 22:02  玩玩就好7744  阅读(57)  评论(0编辑  收藏  举报