SAP + GAP 邻接表:https://blog.csdn.net/Adolphrocs/article/details/84779575
dinic 邻接表:https://blog.csdn.net/Adolphrocs/article/details/84779691
dinic 邻接矩阵:https://blog.csdn.net/Adolphrocs/article/details/84779732
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAXN 222
#define inf 100001000
int map[MAXN][MAXN];//存图
int pre[MAXN];//记录当前点的前驱
int level[MAXN];//记录距离标号
int gap[MAXN];//gap常数优化
int NV, NE;
//入口参数vs源点,vt汇点
int SAP(int vs, int vt){
memset(pre, -1, sizeof(pre));
memset(level, 0, sizeof(level));
memset(gap, 0, sizeof(gap));
gap[0] = vt;
int v, u = pre[vs] = vs, maxflow = 0, aug = inf;
while (level[vs] < vt) {
//寻找可行弧
for(v = 1; v <= vt; v++) {
if(map[u][v] > 0 && level[u] == level[v] + 1){
break;
}
}
if(v <= vt){
pre[v] = u;
u = v;
if(v == vt){
aug = inf;
//寻找当前找到的一条路径上的最大流
for(int i = v; i != vs; i = pre[i]){
if(aug > map[pre[i]][i]) aug = map[pre[i]][i];
}
maxflow += aug;
//更新残留网络
for(int i = v; i != vs; i = pre[i]){
map[pre[i]][i] -= aug;
map[i][pre[i]] += aug;
}
u = vs;//从源点开始继续搜
}
}else {
//找不到可行弧
int minlevel = vt;
//寻找与当前点相连接的点中最小的距离标号
for(v = 1; v <= vt; v++){
if(map[u][v] > 0 && minlevel > level[v]){
minlevel = level[v];
}
}
gap[level[u]]--;//(更新gap数组)当前标号的数目减1;
if(gap[level[u]] == 0) break;//出现断层
level[u] = minlevel + 1;
gap[level[u]]++;
u = pre[u];
}
}
return maxflow;
}
int main(){
int n, m, u, v, cap;
while(~scanf("%d%d", &m, &n)){
memset(map, 0, sizeof(map));
for(int i = 1; i <= m; i++){
scanf("%d%d%d", &u, &v, &cap);
map[u][v] += cap;
}
printf("%d\n", SAP(1, n));
}
return 0;
}