HDU 4292 Food 最大流
Food
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7825 Accepted Submission(s): 2591
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.
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).
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
建圖:源點-->所有food,所有drink-->匯點,每個person拆成兩個點food連對應person_1,person_2連對應drink,person_1連person_2,跑一邊最大流
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<map>
#include<queue>
using namespace std;
const int maxm = 50005;
const int INF = 1e9 + 7;
struct node
{
int u, v, flow, next;
}edge[maxm * 8];
int n, m, s, t, cnt, f, d;
int head[maxm], dis[maxm], pre[maxm], cur[maxm];
char str[205][205];
void init()
{
cnt = s = 0, t = 2 * n + f + d + 1;
memset(head, -1, sizeof(head));
}
void add(int u, int v, int flow)
{
edge[cnt].u = u, edge[cnt].v = v, edge[cnt].flow = flow;
edge[cnt].next = head[u], head[u] = cnt++;
edge[cnt].u = v, edge[cnt].v = u, edge[cnt].flow = 0;
edge[cnt].next = head[v], head[v] = cnt++;
}
int bfs()
{
queue<int>q;
memset(dis, -1, sizeof(dis));
dis[s] = 0;
q.push(s);
while (!q.empty())
{
int u = q.front();q.pop();
for (int i = head[u];i != -1;i = edge[i].next)
{
int v = edge[i].v;
if (dis[v] == -1 && edge[i].flow)
{
dis[v] = dis[u] + 1;
q.push(v);
}
}
}
if (dis[t] == -1) return 0;
return 1;
}
int dfs(int u, int flow)
{
if (u == t) return flow;
for (int &i = cur[u];i != -1;i = edge[i].next)
{
int v = edge[i].v;
if (dis[v] == dis[u] + 1 && edge[i].flow)
{
int d = dfs(v, min(edge[i].flow, flow));
if (d > 0)
{
edge[i].flow -= d;
edge[i ^ 1].flow += d;
return d;
}
}
}
return 0;
}
int dinic()
{
int ans = 0;
while (bfs())
{
for (int i = s;i <= t;i++) cur[i] = head[i];
while (d = dfs(s, INF))
ans += d;
}
return ans;
}
int main()
{
int i, j, k, sum, x;
while (scanf("%d%d%d", &n, &f, &d) != EOF)
{
init();
for (i = 1;i <= f;i++)
{
scanf("%d", &x);
add(s, i, x);
}
for (i = 1;i <= d;i++)
{
scanf("%d", &x);
add(f + 2 * n + i, t, x);
}
for (i = 1;i <= n;i++)
{
scanf("%s", str[i] + 1);
add(f + i, f + n + i, 1);
for (j = 1;j <= f;j++)
{
if (str[i][j] == 'Y')
add(j, f + i, INF);
}
}
for (i = 1;i <= n;i++)
{
scanf("%s", str[i] + 1);
for (j = 1;j <= d;j++)
{
if (str[i][j] == 'Y')
add(f + n + i, f + 2 * n + j, INF);
}
}
printf("%d\n", dinic());
}
return 0;
}