ISAP 时间复杂度最坏 O(n*n*m) 与dinic都是增广路算法,但是ISAP只需要bfs一次所以基本上要比dinic要快不少。
code
#include <iostream> #include <string> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <functional> #include <map> #include <set> #include <stack> #define FT(a, b) memset(a, b, sizeof(a)) #define FAT(a) memset(a, 0, sizeof(a)) using namespace std; typedef long long ll; const int M = 3e5 + 10; const int N = 2e4 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int n, m, s, t; int h[N], e[M], ne[M], w[M], idx; int deepth[N], gap[N]; void add(int a, int b, int c) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } void bfs() { FT(deepth, -1); FAT(gap); queue<int> q; q.push(t); deepth[t] = 0; gap[0] = 1; while (q.size()) { int a = q.front(); q.pop(); for (int i = h[a]; ~i; i = ne[i]) { int j = e[i]; if (deepth[j] == -1) { deepth[j] = deepth[a] + 1; gap[deepth[j]]++; q.push(j); } } } } // int ans; int dfs(int now, int flow) { if (now == t) { // ans += flow; return flow; } int nowflow = 0; for (int i = h[now]; ~i; i = ne[i]) { int j = e[i]; if (w[i] && deepth[j] + 1 == deepth[now]) { int k = dfs(j, min(flow - nowflow, w[i])); w[i] -= k, w[i ^ 1] += k, nowflow += k; if (nowflow == flow) return nowflow; } } --gap[deepth[now]]; if (!gap[deepth[now]]) gap[s] = n + 2; ++deepth[now]; ++gap[deepth[now]]; return nowflow; } int ISAP() { int ans = 0; bfs(); while (gap[s] < n) ans += dfs(s, INF); return ans; } int main() { #ifdef ONLINE_JUDGE #else freopen("D://code//c++//in.txt", "r", stdin); #endif scanf("%d%d%d%d", &n, &m, &s, &t); FT(h, -1); idx = 0; for (int i = 0; i < m; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c), add(b, a, 0); } printf("%d\n", ISAP()); return 0; }