带当前弧优化 gap优化的sap 甚至省去了开始的bfs分层
虽然花了一些时间了解原理 但是感觉不亏 现在能完全独立靠原理写出具体实现了
#include<cstdio> #include<cstring> using namespace std; const int maxn = 1007, maxm = 10007, 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 = 0; memset(head, -1, sizeof head); } void addedge(int u, int v, int w){ edge[tot] = Edge(u, v, head[u], w, 0); head[u] = tot++; edge[tot] = Edge(v, u, head[v], 0, 0); head[v] = tot++; } int sap(){ memset(gap, 0, sizeof (gap)); memset(dep, 0, sizeof (dep)); memcpy(cur, head, sizeof (head)); int u = st; pre[u] = -1; gap[0] = n; int ans = 0; while(dep[st] < n){ if(u == ed){ int MIN = inf; for(int i = pre[u]; i != -1; 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 != -1; i = pre[edge[i].u]){ edge[i].f += MIN; edge[i^1].f -= MIN; } u = st; ans += MIN; continue; } bool flag = false; int v; for(int i = cur[u]; i != -1; i = edge[i].nxt){ v = edge[i].v; if(edge[i].w - edge[i].f && dep[v]+1 == dep[u]){ flag = true; cur[u] = pre[v] = i; break; } } if(flag){ u = v; continue; } int MIN = n; for(int i = head[u]; i != -1; 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+1; gap[dep[u]]++; if(u != st) u = edge[pre[u]].u; } return ans; } int main(){ int t, kase = 1; 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 = 1, ed = n; printf("Case %d: ", kase++); printf("%d\n", sap()); } return 0; }
时间: 2024-11-15 00:41:59