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;
}
$——by\quad wanwanjiuhao7744$