Hdu 4292 Food (最大流)

题目链接:

  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模板。

  1 #include <queue>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 using namespace std;
  7 
  8 const int maxn = 810;
  9 const int N = 900000;
 10 const int INF = 0x3f3f3f3f;
 11 struct Node
 12 {
 13     int to, next, flow;
 14 } edge[N];
 15 int head[maxn], Layer[maxn], s, e, tot;
 16 int vis[maxn];
 17 
 18 void Add (int from, int to, int flow)
 19 {
 20     edge[tot].to = to;
 21     edge[tot].flow = flow;
 22     edge[tot].next = head[from];
 23     head[from] = tot++;
 24 }
 25 
 26 bool CountLayer ()
 27 {
 28     queue <int> Q;
 29     memset (Layer, 0, sizeof(Layer));
 30     Q.push(s);
 31     Layer[s] = 1;
 32     
 33     while (!Q.empty())
 34     {
 35         int u = Q.front();
 36         Q.pop();
 37         for (int i=head[u]; i!=-1; i=edge[i].next)
 38         {
 39             int v = edge[i].to;
 40             if (!Layer[v] && edge[i].flow)
 41             {
 42                 Layer[v] = Layer[u] + 1;
 43                 Q.push(v);
 44                 if (v == e)
 45                     return true;
 46             }
 47         }
 48     }
 49 
 50     return false;
 51 }
 52 
 53 int dfs (int start, int end, int maxflow)
 54 {
 55     if (start == end)
 56         return maxflow;
 57         
 58     int uflow = 0;
 59     for (int i=head[start]; i!=-1; i=edge[i].next)
 60     {
 61         
 62         int v = edge[i].to;
 63         if (Layer[v]==Layer[start]+1 && edge[i].flow)
 64         {
 65             int flow = min (maxflow-uflow, edge[i].flow);
 66             flow = dfs (v, end, flow);
 67             
 68             uflow += flow;
 69             edge[i].flow -= flow;
 70             edge[i^1].flow += flow;
 71             
 72             if (maxflow == uflow)
 73                 break;
 74         }
 75     }
 76     
 77     if (uflow == 0)
 78         Layer[start] = 0;
 79         return uflow;
 80 }
 81 int dinic ( )
 82 {
 83     int maxflow = 0;
 84     
 85     while (CountLayer ())
 86         maxflow += dfs (s, e, INF);
 87         
 88     return maxflow;
 89 }
 90 int main ()
 91 {
 92     char str[maxn];
 93     int n, f, d, v;
 94     
 95     while (scanf ("%d %d %d", &n, &f, &d) != EOF)
 96     {
 97         memset (head, -1, sizeof(head));
 98         s = tot = 0;
 99         e = f + n + n + d + 1;
100         
101         for (int i=1; i<=f; i++)
102         {
103             scanf ("%d", &v);
104             Add (s, i, v);
105             Add (i, s, 0);
106         }
107 
108         for (int i=f+n+n+1; i<e; i++)
109         {
110             scanf ("%d", &v);
111             Add (i, e, v);
112             Add (e, i, 0);
113         }
114 
115         for (int i=1; i<=n; i++)
116         {
117             scanf ("%s", str+1);
118             for (int j=1; j<=f; j++)
119                 if (str[j] == 'Y')
120                 {
121                     Add (j, f+i, 1);
122                     Add (f+i, j, 0);
123                 }
124         }
125         
126         for (int i=1; i<=n; i++)
127         {
128             scanf ("%s", str+1);
129             for (int j=1; j<=d; j++)
130                 if (str[j] == 'Y')
131                 {
132                     Add (f+n+i, f+n+n+j, 1);
133                     Add (f+n+n+j, f+n+i, 0);
134                 }
135         }
136         
137         for (int i=f+1; i<=f+n; i++)
138         {
139             Add (i, i+n, 1);
140             Add (i+n, i, 0);
141         }
142         
143         printf ("%d
", dinic());
144     }
145     return 0;
146 }
本文为博主原创文章,未经博主允许不得转载。
原文地址:https://www.cnblogs.com/alihenaixiao/p/4748341.html