hdu 4292 Food 【圖論-網路流-最大流-Dinic】
Food
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
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
題目大意:有n個人,每個人都有自己喜歡的食物和飲料,先有F中食物,D中飲料,並給出每個人的喜好,讓你求所給食物和飲料最多能滿足多少人的需求
注:本題和poj3281差不多,現給出我做poj3281時的文章連結:
解題思路也在上面連結的文章裡
知識點:最大流
**所用演算法:**Dinic
AC程式碼:
//Dinic AC
//Ford-Fulkerson Time limit
//EK Time limit
# include <cstdio>
# include <cstring>
# include <queue>
using namespace std;
# define MAXN 10005
# define MAXM 200005 //陣列開小了 超時了好多次
# define INF 1 << 30
struct EDGE
{
int to;
int w;
int next;
}edge[MAXM];
int tot;
int head[MAXN];
int dis[MAXN];
int min(int a, int b)
{
return a > b ? b : a;
}
void Init()
{
tot = 0;
memset(head, -1, sizeof(head));
}
void Addedge(int u, int v, int w)
{
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
edge[tot].to = u;
edge[tot].w = 0;
edge[tot].next = head[v];
head[v] = tot++;
}
bool Bfs(int s, int t)
{
memset(dis, 0, sizeof(dis));
queue<int> que;
dis[s] = 1;
que.push(s);
while (!que.empty())
{
int u = que.front(); que.pop();
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if (dis[v] == 0 && edge[i].w > 0)
{
dis[v] = dis[u] + 1;
if (v == t)
{
return true;
}
que.push(v);
}
}
}
return false;
}
int Dfs(int u, int t, int f)
{
if (u == t)
{
return f;
}
int cost = 0;
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
int w = edge[i].w;
if (dis[v] == dis[u] + 1 && w > 0)
{
int d = Dfs(v, t, min(w, f - cost));
if (d > 0)
{
edge[i].w -= d;
edge[i ^ 1].w += d;
cost += d;
if (cost == f)
{
break;
}
else
{
dis[v] = -1;
}
}
}
}
return cost;
}
int Dinic(int s, int t)
{
int maxflow = 0;
while (Bfs(s, t))
{
maxflow += Dfs(s, t, INF);
}
return maxflow;
}
int main(void)
{
int n, f, d;
while (scanf("%d %d %d", &n, &f, &d) != EOF)
{
Init();
int i, j;
int s = 0;
int t = n * 2 + f + d + 1;
for (i = 1; i <= f; i++)
{
int w;
scanf("%d", &w);
Addedge(s, i, w);
}
for (i = 1; i <= d; i++)
{
int w;
scanf("%d", &w);
Addedge(f + 2 * n + i, t, w);
}
for (i = 1; i <= n; i++)
{
Addedge(f + i, f + n + i, 1);
}
char str[MAXN];
for (i = 1; i <= n; i++)
{
scanf("%s", &str[1]);
for (j = 1; j <= f; j++)
{
if (str[j] == 'Y')
{
Addedge(j, f + i, 1);
}
}
}
for (i = 1; i <= n; i++)
{
scanf("%s", &str[1]);
for (j = 1; j <= d; j++)
{
if (str[j] == 'Y')
{
Addedge(f + n + i, f + 2 * n + j, 1);
}
}
}
printf("%d\n", Dinic(s, t));
}
return 0;
}