Food
Time Limit: 1000ms
Memory Limit: 32768KB
This problem will be judged on HDU. Original ID: 429264-bit integer IO format: %I64d Java class name: Main
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
解题:最大流,人拆点 边流为1
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int INF = 0x3f3f3f3f; 4 const int maxn = 1010; 5 struct arc { 6 int to,flow,next; 7 arc(int x = 0,int y = 0,int z = -1) { 8 to = x; 9 flow = y; 10 next = z; 11 } 12 } e[maxn*maxn]; 13 int head[maxn],cur[maxn],d[maxn],tot,S,T; 14 void add(int u,int v,int flow) { 15 e[tot] = arc(v,flow,head[u]); 16 head[u] = tot++; 17 e[tot] = arc(u,0,head[v]); 18 head[v] = tot++; 19 } 20 queue<int>q; 21 bool bfs() { 22 while(!q.empty()) q.pop(); 23 memset(d,-1,sizeof d); 24 q.push(S); 25 d[S] = 1; 26 while(!q.empty()) { 27 int u = q.front(); 28 q.pop(); 29 for(int i = head[u]; ~i; i = e[i].next) { 30 if(e[i].flow && d[e[i].to] == -1) { 31 d[e[i].to] = d[u] + 1; 32 q.push(e[i].to); 33 } 34 } 35 } 36 return d[T] > -1; 37 } 38 int dfs(int u,int low) { 39 if(u == T) return low; 40 int tmp = 0,a; 41 for(int &i = cur[u]; ~i; i = e[i].next) { 42 if(e[i].flow && d[u]+1==d[e[i].to]&&(a=dfs(e[i].to,min(low,e[i].flow)))) { 43 low -= a; 44 tmp += a; 45 e[i].flow -= a; 46 e[i^1].flow += a; 47 if(!low) break; 48 } 49 } 50 if(!tmp) d[u] = -1; 51 return tmp; 52 } 53 int dinic() { 54 int ret = 0; 55 while(bfs()) { 56 memcpy(cur,head,sizeof cur); 57 ret += dfs(S,INF); 58 } 59 return ret; 60 } 61 char str[maxn]; 62 int main() { 63 int N,F,D,flow; 64 while(~scanf("%d%d%d",&N,&F,&D)) { 65 memset(head,-1,sizeof head); 66 S = tot = 0; 67 T = 1000; 68 for(int i = 1; i <= F; ++i) { 69 scanf("%d",&flow); 70 add(S,i,flow); 71 } 72 for(int i = 1; i <= D; ++i) { 73 scanf("%d",&flow); 74 add(F + i,T,flow); 75 } 76 for(int i = 1; i <= N; ++i) { 77 add(F + D + i*2-1,F + D + i*2,1); 78 scanf("%s",str); 79 for(int j = 0; str[j]; ++j) 80 if(str[j] == 'Y') add(j+1, F + D + i*2 - 1,INF); 81 } 82 for(int i = 1; i <= N; ++i) { 83 scanf("%s",str); 84 for(int j = 0; str[j]; ++j) 85 if(str[j] == 'Y') add(F + D + i*2,F + j + 1,INF); 86 } 87 printf("%d ",dinic()); 88 } 89 return 0; 90 }