Food
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2132 Accepted Submission(s): 742
Problem Description
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.
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).
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
1 1 1
1 1 1
YYN
NYY
YNY
YNY
YNY
YYN
YYN
NNY
Sample Output
3
/****************************************
* author:crazy_石头
* algorithm:sap+当前弧+gap优化
* date:2013/09/29
* problem:HDU4292拆点网络流
*****************************************/
#include<cstdio>
#include<cstring>
#include<climits>
using namespace std;
#define N 90005
#define M 4000005
#define INF INT_MAX
const int maxn=500;
int source,sink,nodenum;
int num,pre[N],dis[N],gap[N],head[N],cur[N];
struct node
{
int u,v,w;
int next;
}e[M];
inline void add(int u,int v,int w)
{
e[num].u=u;
e[num].v=v;
e[num].w=w;
e[num].next=head[u];
head[u]=num++;
}
inline void addedge(int u,int v,int w)
{
add(u,v,w);
add(v,u,0);
}
inline int max(int a,int b)
{
return a>b?a:b;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline int isap(int s,int t,int n)
{
int top,mindis,maxflow=0,v,i,aug;
bool flag;
for(i=0;i<=n;i++)
{
cur[i]=head[i];
gap[i]=dis[i]=0;
}
top=pre[s]=s;
aug=INF;
while(dis[s]<n)
{
flag=0;
for(i=cur[top];i!=-1;i=e[i].next)
{
v=e[i].v;
if(e[i].w>0&&dis[top]==dis[v]+1)
{
flag=1;
break;
}
}
if(flag)
{
pre[v]=top;
cur[top]=i;
aug=min(aug,e[i].w);
top=v;
if(top==t)
{
while(top!=s)
{
top=pre[top];
e[cur[top]].w-=aug;
e[cur[top]^1].w+=aug;
}
top=s;
maxflow+=aug;
aug=INF;
}
}
else
{
if(--gap[dis[top]]==0)
break;
mindis=n;
cur[top]=head[top];
for(i=head[top];i!=-1;i=e[i].next)
{
v=e[i].v;
if(e[i].w>0&&dis[v]+1<mindis)
{
mindis=dis[v]+1;
cur[top]=i;
}
}
dis[top]=mindis;
gap[mindis]++;
if(top!=s)
top=pre[top];
}
}
return maxflow;
}
inline void init()
{
num=0;
memset(head,-1,sizeof(head));
}
int food[maxn],drink[maxn];
char str[maxn];
int main()
{
int n,foodnum,drinknum,i,j;
while(~scanf("%d%d%d",&n,&foodnum,&drinknum))
{
init();
source=0,sink=n*2+foodnum+drinknum+1,nodenum=sink;
for(i=1;i<=foodnum;i++)
{
scanf("%d",&food[i]);
addedge(source,i,food[i]);
}
for(i=1;i<=drinknum;i++)
{
scanf("%d",&drink[i]);
addedge(foodnum+i,sink,drink[i]);
}
for(i=1;i<=n;i++)
{
addedge(foodnum+drinknum+i,foodnum+drinknum+n+i,1);
}
for(i=1;i<=n;i++)
{
scanf("%s",str+1);
for(j=1;j<=foodnum;j++)
{
if(str[j]=='Y')
{
addedge(j,foodnum+drinknum+i,1);
}
}
}
for(i=1;i<=n;i++)
{
scanf("%s",str+1);
for(j=1;j<=drinknum;j++)
{
if(str[j]=='Y')
{
addedge(foodnum+drinknum+i+n,foodnum+j,1);
}
}
}
int res=isap(source,sink,nodenum);
printf("%d\n",res);
}
return 0;
}