Food
Time Limit: 2000/1000 MS (Java/others) memory limit: 32768/32768 K (Java/Others)
Total submission (s): 2664 accepted submission (s): 899
Problem description you, a part-time dining service worker in your college's dining hall, are now confused with a new problem: serve as your 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 cocould 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 your people as possible. so you must decide a plan where some people are served while requirements of the rest of them are unmet. you shoshould notice that, when one's requirement is unmet, he/she woshould 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. certificate e jth character in the ith one of these lines denotes whether people I wowould accept food J. "Y" for yes and "N" for no.
Following is N line, each consisting of a string of length D. authorization e jth character in the ith one of these lines denotes whether people I wowould 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 31 1 11 1 1YYNNYYYNYYNYYNYYYNYYNNNY
Sample output
3
F foods, N people, d drinks
First, enter a row of F numbers indicating the amount of each type of food;
Enter D numbers for each type of beverage;
Then n rows are the types of foods that everyone can accept. The first Y represents the first type of food that everyone can accept.
N more lines are the types of drinks that everyone can accept,
Everyone only gives him one food or drink.
The method is to set a super source point beg, which is connected to various foods. The weight is the amount of the food.
Split each person into a nod and a dot. Because only one is eaten, the weight is 1;
Then we connect the various foods to people's heads according to their hobbies. Because we only eat one food, the weight is 1.
When each person's vertex is connected to a beverage based on his or her hobbies, the weight is also 1;
Set another super collection point fin to connect various drinks to fin;
Create a graph like this
# Include <stdio. h> # include <string. h> # include <queue> using namespace STD; # define INF 1000000 # define n 1000 # define M 100000 // n is the number of points M is the number of sides 200 400 200 inline int min (int A, int B) {return A> B? B: A;} // note that this type is intstruct edge {int from, to, Cap, NEX;} edge [M * 2]; // bidirectional edge, note that the re template is effective at the same time as the edge at the starting vertex rather than removing the int head [N], edgenum; // The two must be initialized-1 and 0 void Init () {memset (Head,-1, sizeof (head); edgenum = 0;} void addedge (int u, int V, int cap) {// apply reverse arc edge e = {u, v, Cap, head [u]} to network streams; edge [edgenum] = E; head [u] = edgenum ++; edge e2 = {v, U, 0, head [v]}; // if the cap here is a unidirectional edge, it must be 0 edge [edgenum] = e2; head [v] = edgenum ++;} int dis [N], cur [N]; // dis [I] indicates the distance from the I point to the starting point. cur [I] indicates the edge being considered in the edge connected to the I point. Edge optimization is not considered. The used vertex is initialized to headbool. vis [N]; bool BFS (INT start, int end) {// run memset (VIS, 0, sizeof (VIS); memset (DIS,-1, sizeof (DIS); queue <int> q; q. push (start); DIS [start] = 0; vis [start] = 1; while (! Q. Empty () {int u = Q. Front (); q. Pop (); For (INT I = head [u]; I! =-1; I = edge [I]. NEX) {edge e = edge [I]; If (! Vis [E. to] & E. cap> 0) {vis [E. to] = true; DIS [E. to] = dis [u] + 1; if (E. to = END) return true; q. push (E. to) ;}}return false;} int DFS (int x, int A, int end) {// The current inbound traffic X is a traffic a is the minimum value of all edge weights in the outbound traffic if (x = end | A = 0) return; int flow = 0, F; // flow indicates the flow from point X to all points below. The maximum traffic is for (Int & I = cur [X]; I! =-1; I = edge [I]. NEX) {edge & E = edge [I]; If (DIS [x] + 1 = dis [E. to] & (F = DFS (E. to, min (A, E. CAP), end)> 0) {e. cap-= f; edge [I ^ 1]. cap + = f; // flow + = f; A-= f; if (a = 0) Break ;}} return flow;} must be removed from the reverse side ;} int maxflow (INT start, int end) {int flow = 0; while (BFS (START, end) {// memcpy (cur, head, sizeof (head); // copy the head array to flow + = DFS (START, INF, end);} return flow;} int main () {int fin, beg; int I, j, F, n, D, TEM; char a [300]; while (scanf ("% d", & N, & F, & D )! = EOF) // F points represent food, 2 * n points represent D points represent drinks {Init (); fin = F + 2 * n + D + 1; beg = 0; for (I = 1; I <= f; I ++) {scanf ("% d \ n", & TEM); addedge (beg, I, TEM) ;}for (I = 1; I <= D; I ++) {scanf ("% d \ n", & TEM ); addedge (I + F + 2 * n, FIN, TEM) ;}for (I = 1; I <= N; I ++) {scanf ("% s ", a); For (j = 0; j <F; j ++) {if (a [J] = 'y') {addedge (J + 1, F + I, 1); // food to people} addedge (F + I, F + I + N, 1 ); // Number of people} for (I = 1; I <= N; I ++) // person {scanf ("% s", ); for (j = 0; j <D; j ++) {if (a [J] = 'y') {addedge (F + I + N, F + 2 * n + J + 1, 1); // enter beverage} printf ("% d \ n", maxflow (beg, fin ));} return 0 ;}