/*
Each person has his/her favorite food and drinks. Each person chooses only one quantity of food and one quantity of drinks !?
Idea: creating images is very important! F-food, p-people, D-drink
Figure: 0 (source point) ---> f ---> P ----> p '----> D ---> T (sink point)
Splitting people is very important, because each person can only have one choice at most, that is, the maximum traffic of P ---> P is 1!
If you still don't know, let's take a look at the example to tell you the difference between splitting people and not splitting people!
*/
1 # include <iostream> 2 # include <cstring> 3 # include <cstdio> 4 # include <algorithm> 5 # include <vector> 6 # include <queue> 7 # define n 850 8 # define M 201000 9 # define INF 0x3f3f3f3f 10 using namespace STD; 11 12 struct edge {13 int V, Cap, NT; 14}; 15 16 int first [N]; 17 edge G [m]; 18 int CNT; 19 int N, f, D; 20 21 void addedge (int u, int V, int cap) {22g [CNT]. V = V; 23g [CNT]. CAP = CAP; 24g [CNT]. nt = Fi RST [u]; 25 first [u] = CNT ++; 26 27G [CNT]. V = u; 28g [CNT]. CAP = 0; 29G [CNT]. nt = first [v]; 30 first [v] = CNT ++; 31} 32 33 int ans, SS; 34 35 queue <int> q; 36 int Dist [N]; 37 38 bool BFS () {39 memset (Dist, 0, sizeof (DIST); 40 Dist [0] = 1; 41 Q. push (0); 42 while (! Q. Empty () {43 int u = Q. Front (); 44 Q. Pop (); 45 for (int e = first [u]; ~ E; E = G [e]. nt) {46 int v = G [e]. V; 47 int Cap = G [e]. CAP; 48 if (! Dist [v] & Cap> 0) {49 Dist [v] = DIST [u] + 1; 50 Q. push (V); 51} 52} 53} 54 if (Dist [ss + 1] = 0) return false; 55 return true; 56} 57 58 int DFS (int u, int flow) {59 int ff; 60 if (u = SS + 1) return flow; 61 for (int e = first [u]; ~ E; E = G [e]. NT) {62 int v = G [e]. v; 63 int Cap = G [e]. CAP; 64 if (Dist [v] = DIST [u] + 1 & Cap> 0 & (FF = DFS (v, min (Cap, flow )))) {65g [e]. cap-= ff; 66G [E ^ 1]. cap + = ff; 67 return ff; 68} 69} 70 Dist [u] =-1; // indicates that the u node cannot reach the sink! 71 return 0; 72} 73 74 void dinic () {75 ans = 0; 76 int D; 77 while (BFS () 78 while (D = DFS (0, INF) 79 ans + = D; 80} 81 82 int main () {83 while (scanf ("% d", & N, & F, & D )! = EOF) {84 Ss = 2 * n + F + D; 85 CNT = 0; 86 memset (first,-1, sizeof (first )); 87 for (INT I = 1; I <= f; ++ I) {// create a directed edge from The Source Vertex. The maximum traffic is 88 int X; 89 scanf ("% d", & X); 90 addedge (0, I, x); 91} 92 93 for (INT I = 1; I <= D; + + I) {// set up a directed edge for drinking to the sink. The maximum traffic is the number of drinks 94 int X; 95 scanf ("% d", & X ); 96 addedge (N * 2 + F + I, SS + 1, x); 97} 98 for (INT I = 1; I <= N; ++ I) {// create a directed edge for the person who eats the food. The maximum traffic is 1 99 getchar (); 100 for (Int J = 1; j <= f; ++ J) {101 char ch; 102 Scanf ("% C", & Ch); 103 If (CH = 'y') 104 addedge (J, F + I, 1 ); 105} 106} 107 108 For (INT I = 1; I <= N; ++ I) {// creates a directed edge for a person to drink, the maximum traffic is 1 109 addedge (F + I, n + F + I, 1); // the person belongs to the node capacity and splits the person, because each person can only have one choice! 110 getchar (); 111 for (Int J = 1; j <= D; ++ J) {112 char ch; 113 scanf ("% C", & Ch ); 114 If (CH = 'y') 115 addedge (n + F + I, F + N * 2 + J, 1); 116} 117 118 dinic (); 120 printf ("% d \ n", ANS); 121} 122 return 0; 123}
Hdu4292food (maximum stream dinic algorithm)