You, a part-time dining service worker in your college’s dining hall, are now confused with a new problem: serve as many people as possible.
The issue comes up as people in your college are more and more difficult to serve with meal: They eat only some certain kinds of food and drink, and with requirement unsatisfied, go away directly.
You have prepared F (1 <= F <= 200) kinds of food and D (1 <= D <= 200) kinds of drink. Each kind of food or drink has certain amount, that is, how many people could this food or drink serve. Besides, You know there’re N (1 <= N <= 200) people and you too can tell people’s personal preference for food and drink.
Back to your goal: to serve as many people as possible. So you must decide a plan where some people are served while requirements of the rest of them are unmet. You should notice that, when one’s requirement is unmet, he/she would just go away, refusing any service.
For each test case, the first line contains three numbers: N,F,D, denoting the number of people, food, and drink.
The second line contains F integers, the ith number of which denotes amount of representative food.
The third line contains D integers, the ith number of which denotes amount of representative drink.
Following is N line, each consisting of a string of length F. �e jth character in the ith one of these lines denotes whether people i would accept food j. “Y” for yes and “N” for no.
Following is N line, each consisting of a string of length D. �e jth character in the ith one of these lines denotes whether people i would accept drink j. “Y” for yes and “N” for no.
Please process until EOF (End Of File).
#include <bits/stdc++.h> #define maxn 10005 using namespace std; struct Person { string food,drink; }person[maxn]; const int inf= 1e9; struct Edge { int u,v,c,flow; Edge(int a,int b,int cc,int f):u(a),v(b),c(cc),flow(f){} }; struct Dinic { int s,t; vector<Edge> edges; vector<int> pre[maxn]; bool vis[maxn]; int dist[maxn]; int cur[maxn]; void init() { for(int i=0;i<maxn;i++) { pre[i].clear(); } edges.clear(); } void Addedge(int u,int v,int f) { edges.push_back(Edge(u,v,f,0)); edges.push_back(Edge(v,u,0,0)); int mm=edges.size(); pre[u].push_back(mm-2); pre[v].push_back(mm-1); } bool bfs() { memset(vis,false,sizeof(vis)); queue<int> q; q.push(s); vis[s]=1; dist[s]=0; while(!q.empty()) { int now=q.front(); q.pop(); for(int i=0;i<pre[now].size();i++) { Edge &e=edges[pre[now][i]]; if(!vis[e.v]&&e.c>e.flow) { dist[e.v]=dist[now]+1; vis[e.v]=true; q.push(e.v); } } } return vis[t]; } int dfs(int x,int cap) { if(x==t||cap==0) return cap; int f,flow=0; for(int &i=cur[x];i<pre[x].size();i++) { cur[x]=i; Edge &e=edges[pre[x][i]]; if(dist[e.v]==dist[x]+1&&(f=dfs(e.v,min(cap,e.c-e.flow)))) { e.flow+=f; edges[pre[x][i]^1].flow-=f; flow+=f; cap-=f; if(cap==0) break; } } return flow; } int Maxflow(int s,int t) { this->s=s; this->t=t; int flow=0; while(bfs()) { memset(cur,0,sizeof(cur)); flow+=dfs(s,inf); } return flow; } }dc; int main() { int n,f,d,i; while(cin>>n>>f>>d) { dc.init(); int a[maxn]={0}; int b[maxn]={0}; for(i=1;i<=f;i++) { scanf("%d",&a[i]); } for(i=1;i<=d;i++) { scanf("%d",&b[i]); } for(i=1;i<=n;i++) { cin>>person[i].food; } for(i=1;i<=n;i++) { cin>>person[i].drink; } for(i=1;i<=n;i++) { for(int j=0;j<f;j++) { if(person[i].food[j]=='Y') { dc.Addedge(j+1,f+i,1); } } } for(i=1;i<=n;i++) { dc.Addedge(f+i,f+n+i,1); } for(i=1;i<=n;i++) { for(int j=0;j<d;j++) { if(person[i].drink[j]=='Y') { dc.Addedge(f+n+i,f+2*n+j+1,1); } } } for(i=1;i<=f;i++) { dc.Addedge(0,i,a[i]); } for(i=1;i<=d;i++) { dc.Addedge(f+2*n+i,f+2*n+d+1,b[i]); } printf("%d ",dc.Maxflow(0,f+2*n+d+1)); } return 0; }