网络流(dinic)

传说有一个EK算法,时间复杂度是O(n*m^2)的,我想学这个,然后被大家给阻止了,因为有一个比较棒的dinic算法,时间复杂度是O(n^2*m)的。
网络流大概是这样的问题:
一个水的发源点S(可以提供无限量的水),一个汇集点T,水从发源点要流过许多容量一定的管道后,最后回到汇集点,求最大能流多少水。
想一想也知道,最大流量跟管子的容量肯定有关,并且想达到最大能流的水量,必然有某几个管道已经里面装满了水。
引入概念:
容量网络:图G(V,E)为有向网络,在V中指定一个源点和一个汇点,流量从源点出发经过有向网络流向汇点。对于每一条有向边有权值C,称作弧的容量。有向边称为弧。这样的有向网络称为容量网络。(可以粗略理解为现在我们面临的处境(问题描述))
残留网络:假设一条边容量为A,流量为B,那残余容量就是A-B,而以残余容量为边的有向网络就是残留网络。
饱和:容量等于流量。
零流:流量为0.
前(后)向弧:在S—-T的路径上与路径相同(反)的有向边。
增广路:就是S—-T的一条可以扩充流量的路径。(也就是说前向弧)
模版大概是这样:

bool bfs(){
    int h = 1, t = 1;CLR(dep,-1);
    dep[q[1] = S ] = 0;
    while(h <= t){int x = q[h ++ ] ;RepG(i,x)if(fl && dep[v] == -1)dep[q[++ t] = v] = dep[x] + 1;}
    return dep[T] > 0;
}
int dfs(int x,int f){
    if(x == T)return f;
    int s = 0,ff;
    RepG(i,x)if(f && fl && dep[v] = dep[x] + 1 && (ff = dfs(v,min (fl,f))))s += ff, fl -= ff,vfl += ff,f -= ff;
    if(!s)dep[x] = -1;
    return s;
}
void save(int u,int vv,int f){edge[cnt].f = f;edge[cnt].next = head[u];edge[cnt].to = vv;head[u] = cnt ++;}
int maxflow(){int s = 0 ; for(;bfs();s += dfs(S,inf));return s;}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值