最大流sap

时间:2023-03-08 19:36:06

带当前弧优化 gap优化的sap 甚至省去了开始的bfs分层

虽然花了一些时间了解原理 但是感觉不亏 现在能完全独立靠原理写出具体实现了

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = , maxm = , inf = 0x3f3f3f3f;
int st, ed, tot, n, m;
struct Edge{
int u, v, nxt, w, f;
Edge(){}
Edge(int u, int v, int nxt, int w, int f):u(u), v(v), nxt(nxt), w(w), f(f){}
}edge[maxm];
int head[maxn], cur[maxn], gap[maxn], dep[maxn], pre[maxn];
void init(){
tot = ;
memset(head, -, sizeof head);
}
void addedge(int u, int v, int w){
edge[tot] = Edge(u, v, head[u], w, );
head[u] = tot++;
edge[tot] = Edge(v, u, head[v], , );
head[v] = tot++;
}
int sap(){
memset(gap, , sizeof (gap));
memset(dep, , sizeof (dep));
memcpy(cur, head, sizeof (head));
int u = st;
pre[u] = -;
gap[] = n;
int ans = ;
while(dep[st] < n){
if(u == ed){
int MIN = inf;
for(int i = pre[u]; i != -; i = pre[edge[i].u]){
if(MIN > edge[i].w - edge[i].f)
MIN = edge[i].w - edge[i].f;
}
for(int i = pre[u]; i != -; i = pre[edge[i].u]){
edge[i].f += MIN;
edge[i^].f -= MIN;
}
u = st;
ans += MIN;
continue;
}
bool flag = false;
int v;
for(int i = cur[u]; i != -; i = edge[i].nxt){
v = edge[i].v;
if(edge[i].w - edge[i].f && dep[v]+ == dep[u]){
flag = true;
cur[u] = pre[v] = i;
break;
}
}
if(flag){
u = v;
continue;
}
int MIN = n;
for(int i = head[u]; i != -; i = edge[i].nxt){
if(edge[i].w - edge[i].f && dep[edge[i].v] < MIN){
MIN = dep[edge[i].v];
cur[u] = i;
}
}
gap[dep[u]]--;
if(!gap[dep[u]])
return ans;
dep[u] = MIN+;
gap[dep[u]]++;
if(u != st)
u = edge[pre[u]].u;
}
return ans;
}
int main(){
int t, kase = ;
scanf("%d", &t);
while(t--){
init();
scanf("%d%d", &n, &m);
while(m--){
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w);
}
st = , ed = n;
printf("Case %d: ", kase++);
printf("%d\n", sap());
}
return ;
}