Food
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2136 Accepted Submission(s): 745
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
Sample Output
3
Source
构图是老生常谈的事情了。
S-->food连边food[i] ;
food-->man1连边1
man1-->man2连边1
mam2-->drink 连边1 ,
diink-->T连边dink[i]
#include <iostream> #include <stdio.h> #include <queue> #include <stdio.h> #include <string.h> #include <vector> #include <queue> #include <set> #include <algorithm> #include <map> #include <stack> #include <math.h> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) using namespace std ; typedef long long LL ; #define MAXN 1000 #define inf 2100000000 int g[MAXN][MAXN],level[MAXN]; int bfs(int n,int s,int t){ int que[1000],head,tail,i; head=tail=0; que[tail++]=s; memset(level,-1,sizeof(level)); level[s]=1; while(head<tail){ int x=que[head++]; for(i=1;i<=n;++i) if((g[x][i])&&(level[i]==-1)){ level[i]=level[x]+1; que[tail++]=i; } } return level[t]+1; } /*n为最大点,s起点 ,t终点 ,图中没有定点0,从1开始到n*/ int dinic(int n,int s,int t){ int maxflow=0,i; while(bfs(n,s,t)){ int pos,path[MAXN],cut=0,low,find; pos=0; path[pos++]=s;find=1; while(1){ find=1; low=inf; while((path[pos-1]!=t)&&(find)){ find=0; for(i=1;i<=n;++i) if((level[i]==level[path[pos-1]]+1)&&(g[path[pos-1]][i])){ path[pos++]=i; find=1; break; } else if (i==n) break; } if(path[pos-1]==t){ for(i=0;i<pos-1;++i){ if(low>g[path[i]][path[i+1]]){ low=g[path[i]][path[i+1]]; cut=i; } } maxflow+=low; for(i=0;i<pos-1;++i){ g[path[i]][path[i+1]]-=low; g[path[i+1]][path[i]]+=low; } pos=cut+1; } else{ if(pos==1) break; else{ level[path[pos-1]]=-1; pos--; } } } } return maxflow; } const int Max_N=208 ; char str[Max_N][Max_N] ; int food[Max_N] ; int drink[Max_N] ; int S ,T ; int main(){ int F , N , D ; while(scanf("%d%d%d",&N,&F,&D)!=EOF){ memset(g,0,sizeof(g)) ; for(int i=1;i<=F;i++) scanf("%d",&food[i]) ; for(int i=1; i<=D ;i++) scanf("%d",&drink[i]) ; for(int i=1;i<=N;i++) scanf("%s",str[i]+1) ; for(int i=1;i<=N;i++) for(int j=1;j<=F;j++){ if(str[i][j]=='Y') g[j][F+i]=1 ; } for(int i=1;i<=N;i++) scanf("%s",str[i]+1) ; for(int i=1;i<=N;i++) for(int j=1;j<=D;j++){ if(str[i][j]=='Y') g[F+N+i][F+N+N+j]=1 ; } for(int i=1;i<=N;i++) g[F+i][F+N+i]=1 ; T=F+N+N+D+1 ; S=F+N+N+D+1+1 ; for(int i=1;i<=D;i++) g[F+N+N+i][T]=drink[i] ; for(int i=1;i<=F;i++) g[S][i]=food[i] ; cout<<dinic(S,S,T)<<endl ; } return 0 ; }