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模板。
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; }
相关文章推荐
- 块匹配跟踪(转)
- 跳转微信功能(学习总结)
- JAVA中implements实现多接口
- WIFI 用的网站
- EditText被输入法覆盖的解决方法
- jquery获取checkbox是否选中
- vs2010下配置CUDA出现kernel launch failed问题,内核无效
- git基础之创建ssh公钥和密钥
- Windows防火墙开启
- 好玩的
- 利用Nginx实现tornado的反向代理
- HiWork走访老朋友Todolist——土豆丝团队
- python 正则分组获取html中匹配值
- 落家
- Java虚拟机详解05----垃圾收集器及GC参数
- Shell算数运算
- Linux下编辑利器vim,vimrc,viminfo的高级用法
- GCD学习
- 复杂网络 有关节点
- Fastboot线刷“复活”之刷机心得(一)——背景简介