您的位置:首页 > 其它

hdu 4292 Food (最大流)

2012-09-17 19:20 447 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4292

题意:

有N个顾客,餐厅里有F中食物,D中饮料。给出每种食物的个数以及每种饮料的个数。还给出两个关系矩阵N*F 和N*D Y表示第i个人对于第j个食物或者饮料是满意的,求出该餐厅能使顾客满意的最多人数。

思路:

这里我们主要是保持每个人能够拿到自己满意的一份食物和一瓶饮料,(注意每个人只能那一份食物和饮料). Food ------ Peole ------- Drink 按这样的思路只要给出一个最大流即可,但是我们要保持每个人只拿到一份食物与饮料所以要将n个点拆成2*n个点每一对加权值为1,其余的就是给出原点s = 0 汇点e = 2*n + f + d + 1了。原点到Food建边加权为数量化 Food到People建边加权为1 People到Drink建边加权为1 Drink到e建边加权为数量.走一遍最大流就好了。。

View Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>

#define CL(a,num) memset((a),(num),sizeof(a))
#define iabs(x)  ((x) > 0 ? (x) : -(x))
#define Min(a,b) (a) > (b)? (b):(a)
#define Max(a,b) (a) > (b)? (a):(b)

#define ll __int64
#define inf 0x7f7f7f7f
#define MOD 100000007
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define test puts("<------------------->")
#define maxn 10000007
#define M 100007
#define N 810
using namespace std;
//freopen("din.txt","r",stdin);

struct node{
int v,w;
int next;
}g[N*N];

int head
,ct;
int n,d,f;
char str[203];
int level
;
int q[maxn];

void init(){
CL(head,-1);
ct = 0;
}
void add(int u,int v,int w){
g[ct].v = v;
g[ct].w = w;
g[ct].next = head[u];
head[u] = ct++;

g[ct].v = u;
g[ct].w = 0;
g[ct].next = head[v];
head[v] = ct++;
}
bool layer(int s,int e){
int i;
CL(level,-1);
level[s] = 0;
int l = 0, r= 0;
q[r] = s;
while (l <= r){
int u = q[l++];
for (i = head[u]; i != -1; i = g[i].next){
int v = g[i].v;
if (level[v] == -1 && g[i].w > 0){
level[v] = level[u] + 1;
q[++r] = v;
if (v == e) return true;
}
}
}
return false;
}
int find(int s,int e){
int top = 1,i;
int ans = 0;
while (top){
int u = (top == 1 ? s : g[q[top - 1]].v);
if (u == e){
int MIN = inf ,pos;
for (i = 1; i < top; ++i){
int tp = q[i];
if (g[tp].w < MIN){
MIN = g[tp].w;
pos = i;
}
}
for (i = 1; i < top; ++i){
int tp = q[i];
g[tp].w -= MIN;
g[tp^1].w += MIN;
}
ans += MIN;
top = pos - 1;
}
else{
for (i = head[u]; i != -1; i = g[i].next){
int v = g[i].v;
if (level[v] == level[u] + 1 && g[i].w > 0){
q[top++] = i;
break;
}
}
if (i == -1){
top--;
level[u] = -1;
}
}
}
return ans;
}
int dinic(int s,int e){
int ans = 0;
while (layer(s,e))  ans += find(s,e);
return ans;
}
int main(){
//freopen("din.txt","r",stdin);
int i,j;
int s,e;
int flow;
while (~scanf("%d%d%d",&n,&f,&d)){
init();
s = 0; e = 2*n + f + d + 1;

for (i = 1; i <= n; ++i)
add(i,i + n,1);

for (i = 1; i <= f; ++i){
scanf("%d",&flow);
add(s,2*n + i,flow);
}
for (i = 1; i <= d; ++i){
scanf("%d",&flow);
add(2*n + f + i,e,flow);
}
for (i = 1; i <= n; ++i){
scanf("%s",str);
for (j = 0; j < f; ++j){
if (str[j] == 'Y'){
add(2*n + j + 1,i,1);
}
}
}
for (i = 1; i <= n; ++i){
scanf("%s",str);
for (j = 0; j < d; ++j){
if (str[j] == 'Y'){
add(i + n,2*n + f + j + 1,1);
}
}
}
printf("%d\n",dinic(s,e));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: