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; }