洛谷 P3376 【模板】网络最大流(最大流dinic算法,模板题)

最大流dinic算法,模板题
EK算法,每次调用一次 bfs,只能找到一条 增光路。
dinic算法每调用一次 bfs, 就可以找到多条的增光路。
本题要点:
1、dinic 步骤
a) 用bfs建立分层图, 实际是一个增广网
b) 建立一个分层图后,再 dfs 在增广网,计算所有可能的增广路上的流量的总和.

2、dinic 算法的剪枝:当前弧优化:
now 数组,记录每个点将要访问的第一条边。
在bfs建立分层图的时候,某个点 x 第一次入队列, now[x] = head[x]。
在 dfs 的过程中,一次处理的多条增光路,这些增光路可能在某个点相交(假设为x点),
就会多次调用函数 dfs(x, long long sum), 每次从 now[x]中,选择第一条要处理的边。
假设 x点有 y, z, w 三条边, x点的上一点是 fax。第一次进入 dfs(x, sum), 处理了 y 边,剩下 z 和 w 边。
但是此时 边 fax --> x 的流量不足,所以无法处理 z和 w边。 这时候,在for循环内,now[x] = i; //当前弧优化,
也就是把x点的将要处理的第一条边设为 了y边。

for(int i = now[x]; i && sum; i = e[i].next)
{
	now[x] = i;	//当前弧优化
	...
}

第二次进入点x,调用函数 dfs(x, sum), 此时的now[x] 指向了y边。

3、dinic 算法的剪枝:去掉增广完毕的点

k = dfs(v, min(sum, e[i].val));
if(k == 0)
	dis[v] = inf;	//剪枝,去掉增广完毕的点 

k = dfs(v, min(sum, e[i].val)); k是表示当前走点v,能流过的最大流量是k, 当k == 0, 说明此点走不通,
直接赋值 dis[v] = inf, 后面就不会进入点v,因为不满足分层图的 (u点到v点有 边) d[u] + 1 == d[v] 的要求。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int MaxN = 520010;
const long long inf = 2005020600;
int n, m, s, t, u, v;
long long w, ans, dis[MaxN];
int tot = 1, now[MaxN], head[MaxN];

struct node
{
   
	int to, next;
	long long val;
}e
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值