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.
Input There are several test cases.
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).
Output For each test case, please print a single line with one integer, the maximum number of people to be satisfied.
Sample Input
4 3 3
1 1 1
1 1 1
YYN
NYY
YNY
YNY
YNY
YYN
YYN
NNY
Sample Output
3
#include
#include
#include
#include
#include
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod=609929123;
const int N=1220;
int n,f,d;
int S,T,R;
struct node
{
int u,v,cap,next;
}es[400*N];
int frist[N];
int dis[N];
int current[N];
void init()
{
memset(frist,-1,sizeof(frist));
R=0;
S=0;
T=f+2*n+d+1;
}
int addedge(int u,int v,int cap)
{
node e1={u,v,cap,frist[u]};
es[R]=e1;
frist[u]=R++;
node e2={v,u,0,frist[v]};
es[R]=e2;
frist[v]=R++;
}
void getmap()
{
int a;
for(int i=1;i<=n;i++)
addedge(f+i,f+n+i,1);
for(int i=1;i<=f;i++)
{
scanf("%d",&a);
addedge(S,i,a);
}
for(int i=1;i<=d;i++)
{
scanf("%d",&a);
addedge(i+2*n+f,T,a);
}
char s[300];
for(int i=1;i<=n;i++)
{
scanf("%s",s);
for(int j=0;jq;
q.push(S);
memset(dis,-1,sizeof(dis));
dis[S]=0;
while(!q.empty())
{
int h=q.front();
q.pop();
if(h==T)
return 1;
for(int i=frist[h];i!=-1;i=es[i].next)
{
int temp=es[i].v;
if(dis[temp]==-1&&es[i].cap)
{
dis[temp]=dis[h]+1;
q.push(temp);
}
}
}
return 0;
}
int dinic(int x,int maxflow)
{
if(x==T) return maxflow;
int flow,f=0;
for(int &i=current[x];i!=-1;i=es[i].next)
{
int temp=es[i].v;
if(dis[temp]==dis[x]+1&&es[i].cap)
{
flow=dinic(temp,min(maxflow-f,es[i].cap));
es[i].cap-=flow;
es[i^1].cap+=flow;
f+=flow;
if(f==maxflow) break;
}
}
return f;
}
int DINIC()
{
int ans=0;
while(bfs())
{
int flow;
memcpy(current,&frist,sizeof(frist));
while(flow=dinic(S,inf))
ans+=flow;
}
return ans;
}
int main()
{
while(~scanf("%d%d%d",&n,&f,&d))
{
init();
getmap();
printf("%d\n",DINIC());
}
}