网络流是什么?
简要介绍:移步 litble的博客
关于Dinic
算法
在E-K
算法中,我们利用BFS
orDFS
中的一种来寻找增广路经
而在Dinic
算法中,需要将两者结合起来使用
定义一个名词:层次
第
i
i
层代表距离源点的最短距离为的点集
利用BFS
将所有点的层次计算出来,再使用DFS
进行增广路的寻找,修改后再进行BFS
…以此类推
显然的,每次增广路径必然要经过每一层,所以每次在DFS
扩展时只扩展下一层次的节点
代码:略
优化
GAP
,SAP
,当前弧优化了解一下?
emm,貌似和ISAP差不多了?
欢迎各位交流
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 10010 , M = 100010;
struct EDGE {
int t,n,flow;
}e[M<<1];
int head[N] , tot = 1 , cur[N];
int f[N] , d[N];
int n , m , s , t;
int read() {
int _ans = 0 , _flag = 1 ;
char _ch = getchar();
while(_ch > '9' || _ch < '0') {
if(_ch == '-') _flag = - _flag;
_ch=getchar();
}
while(_ch >= '0' && _ch <= '9') {_ans = _ans * 10 + _ch - '0'; _ch = getchar();}
return _ans * _flag;
}
void addedge(int u , int v , int w) {
e[++tot].t = v;
e[tot].n = head[u];
e[tot].flow = w;
head[u] = tot;
e[++tot].t = u;
e[tot].n = head[v];
e[tot].flow = 0;
head[v] = tot;
}
int dfs(int now , int flow) {
if(now == t) return flow;
int use = 0;
for(int i = cur[now] ; i ; i = e[i].n) {
cur[now] = i;//当前弧优化
if(e[i].flow && d[e[i].t]+1 == d[now]) {
int temp = dfs(e[i].t , min(flow - use , e[i].flow));
use += temp;
e[i].flow -= temp;
e[i^1].flow += temp;
if(flow == use) return use;
}
}
cur[now] = head[now];
if(!(--f[d[now]])) d[s] = n;
++f[++d[now]];
return use;
}
int main() {
n = read(); m = read();
s = read(); t = read();
for(int i = 1 ; i <= m ; ++ i) {
int u = read() , v = read() , w = read();
addedge(u , v , w);
}
f[0] = n;
int ans = 0;
while(d[s] < n) ans += dfs(s,1<<30);
printf("%d\n" , ans);
return 0;
}