您的位置:首页 > 其它

Hdu 4292 Food (最大流)

2015-08-21 16:52 330 查看
题目链接:

  Hdu 4292 Food

题目描述:

  有n位顾客,f种食物,d种饮料。顾客都有自己喜欢的饮料和食物,每个顾客至少得到一种食物和一种饮料才会在餐厅就餐,否则立马走人。现在问最多能满足几位顾客?

解题思路:

  0作为源点,[1, f] 为食物,0到 [1,f] 建边,边流量为每种食物的数目。[f+1, f+n] 代表顾客,[1, f] 与[f+1, f+n]建边,为了尽量满足更多的顾客,把每个顾客与其喜欢的食物之间的边流量赋为1。为了防止增广路时一个顾客选择多种食物和多种饮料的情况,应该对顾客进行拆点。[f+n+1, f+n+n]也代表顾客,[f+1, f+n] 与 [f+n+1, f+n+n] 之间连边,边流量为1。[f+n+n+1, f+n+n+d]代表饮料,f+n+n+d+1代表汇点,饮料与汇点连边,边的容量为每种饮料的数目。

  这个题目时间卡的有一丢丢紧,扎扎用以前的dinic模板时候果断tle。天真的以为是用了邻接矩阵的原因,然后换成邻接表,还是t的哭瞎!!!!,最后多调试了几次后发现,我以前的dinic模板真的有问题。扎扎今天决定要更新一下dinic模板。

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 810;
const int N = 900000;
const int INF = 0x3f3f3f3f;
struct Node
{
int to, next, flow;
} edge
;
int head[maxn], Layer[maxn], s, e, tot;
int vis[maxn];

void Add (int from, int to, int flow)
{
edge[tot].to = to;
edge[tot].flow = flow;
edge[tot].next = head[from];
head[from] = tot++;
}

bool CountLayer ()
{
queue <int> Q;
memset (Layer, 0, sizeof(Layer));
Q.push(s);
Layer[s] = 1;

while (!Q.empty())
{
int u = Q.front();
Q.pop();
for (int i=head[u]; i!=-1; i=edge[i].next)
{
int v = edge[i].to;
if (!Layer[v] && edge[i].flow)
{
Layer[v] = Layer[u] + 1;
Q.push(v);
if (v == e)
return true;
}
}
}

return false;
}

int dfs (int start, int end, int maxflow)
{
if (start == end)
return maxflow;

int uflow = 0;
for (int i=head[start]; i!=-1; i=edge[i].next)
{

int v = edge[i].to;
if (Layer[v]==Layer[start]+1 && edge[i].flow)
{
int flow = min (maxflow-uflow, edge[i].flow);
flow = dfs (v, end, flow);

uflow += flow;
edge[i].flow -= flow;
edge[i^1].flow += flow;

if (maxflow == uflow)
break;
}
}

if (uflow == 0)
Layer[start] = 0;
return uflow;
}
int dinic ( )
{
int maxflow = 0;

while (CountLayer ())
maxflow += dfs (s, e, INF);

return maxflow;
}
int main ()
{
char str[maxn];
int n, f, d, v;

while (scanf ("%d %d %d", &n, &f, &d) != EOF)
{
memset (head, -1, sizeof(head));
s = tot = 0;
e = f + n + n + d + 1;

for (int i=1; i<=f; i++)
{
scanf ("%d", &v);
Add (s, i, v);
Add (i, s, 0);
}

for (int i=f+n+n+1; i<e; i++)
{
scanf ("%d", &v);
Add (i, e, v);
Add (e, i, 0);
}

for (int i=1; i<=n; i++)
{
scanf ("%s", str+1);
for (int j=1; j<=f; j++)
if (str[j] == 'Y')
{
Add (j, f+i, 1);
Add (f+i, j, 0);
}
}

for (int i=1; i<=n; i++)
{
scanf ("%s", str+1);
for (int j=1; j<=d; j++)
if (str[j] == 'Y')
{
Add (f+n+i, f+n+n+j, 1);
Add (f+n+n+j, f+n+i, 0);
}
}

for (int i=f+1; i<=f+n; i++)
{
Add (i, i+n, 1);
Add (i+n, i, 0);
}

printf ("%d\n", dinic());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: