1. 程式人生 > >HDU 4292 Food 最大流

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;
}