Topic links: HDU-Food 4292
The meaning of problems
There are $ N $ individuals, $ F $ kinds of food, $ D $ kinds of drinks, food and beverages each have a certain amount each person needs to have a number 1 or no demand for each food and drink, asking $ F $ kinds of food and drink up to $ D $ types to meet the needs of individuals much.
Thinking
A man split into two nodes, divided into left and right point point unit, left point to the right edge of the Ministry of points connected capacity of 1, showing a person's contribution to the answer up to 1;
The food source to the representative node connected side, the number corresponding to the capacity of the food, the food to a human in need of such food left side portion connected point, a capacity of 1, 1 represents a demand;
Human right point portion connected to the beverage demand side, the capacity is 1, indicating a demand for the drink, the drink even sink side, the number corresponding to the capacity of the beverage, and then to run the maximum flow.
Code
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using std::queue; const int INF = 0x3f3f3f3f, N = 1000, M = 200000; int head[N], d[N]; int s, t, tot, maxflow; struct Edge { int to, cap, nex; } edge[M]; queue<int> q; void add(int x, int y, int z) { edge[++tot].to = y, edge[tot].cap = z, edge[tot].nex = head[x], head[x] = tot; edge[++tot].to = x, edge[tot].cap = 0, edge[tot].nex = head[y], head[y] = tot; } bool bfs() { memset(d, 0, sizeof(d)); while (q.size()) q.pop(); q.push(s); d[s] = 1; while (q.size()) { int x = q.front(); q.pop(); for (int i = head[x]; i; i = edge[i].nex) { int v = edge[i].to; if (edge[i].cap && !d[v]) { q.push(v); d[v] = d[x] + 1; if (v == t) return true; } } } return false; } int dinic(int x, int flow) { if (x == t) return flow; int rest = flow, k; for (int i = head[x]; i && rest; i = edge[i].nex) { int v = edge[i].to; if (edge[i].cap && d[v] == d[x] + 1) { k = dinic(v, std::min(rest, edge[i].cap)); if (!k) d[v] = 0; edge[i].cap -= k; edge[i^1].cap += k; rest -= k; } } return flow - rest; } void init(int v_num) { tot = 1, maxflow = 0; s = v_num, t = s + 1; memset(head, 0, sizeof(head)); } int main() { int nn, nf, nd; while (~scanf("%d %d %d", &nn, &nf, &nd)) { init(nn * 2 + nf + nd); for (int i = 0, num; i < nf; i++) { scanf("%d", &num); add(s, i, num); } for (int i = 0, num; i < nd; i++) { scanf("%d", &num); add(i + nf, t, num); } char str[210]; for (int i = 0; i < nn; i++) { scanf(" %s", str); for (int j = 0; j < nf; j++) { if (str[j] == 'Y') add(j, i + nf + nd, 1); } add(nf + nd + i, nf + nd + nn + i, 1); } for (int i = 0; i < nn; i++) { scanf(" %s", str); for (int j = 0; j < nd; j++) { if (str[j] == 'Y') add(nn + nf + nd + i, nf + j, 1); } } while (bfs()) maxflow += dinic(s, INF); printf("%d\n", maxflow); } return 0; }