Algorithm 1: DINIC algorithm
/* ID: zhangji42 LANG: C++ TASK: ditch */ #include <cstdio> #include <cstring> #include <fstream> #include <cmath> #include <queue> using namespace std; #define MAXV 210 #define MAXE 210 #define INT_MAX 1 << 29 struct EDGE { int v, w; EDGE *next, *back; } *first[MAXV], *f2[MAXV], *path[MAXV]; EDGE* AddEdge(int u, int v, int w) { EDGE *p = new(EDGE); p->v = v; p->w = w; p->next = first[u]; first[u] = p; return p; } void Insert(int u, int v, int w) { EDGE *x, *y; x = AddEdge(u,v,w); y = AddEdge(v,u,0); x->back = y; y->back = x; } int E, V; int dist[MAXV], pre[MAXV]; bool BFS(int s, int t) { queue<int> Q; memset(dist,-1,sizeof(dist)); while (!Q.empty()) Q.pop(); Q.push(s), dist[s] = 0; while (!Q.empty()) { int now = Q.front(); Q.pop(); for (EDGE *k = first[now]; k != NULL; k = k->next) { if (k->w && dist[k->v] == -1) { dist[k->v] = dist[now]+1; Q.push(k->v); if (k->v == t) return true; } } } return false; } int Dinic(int s, int t) { int i, MaxFlow, curr; bool flag; EDGE* p; for (MaxFlow = 0; BFS(s, t); ) { memcpy(f2, first, sizeof(first)); for (i = s; ; ) { if (i == t) { for (curr = INT_MAX; i != s; i = pre[i]) if (path[i]->w < curr) curr = path[i]->w; for (MaxFlow += curr, i = t; i != s; i = pre[i]) path[i]->w -= curr, path[i]->back->w += curr; } for (flag = false, p = f2[i]; p != NULL; p = p->next) if (p->w && dist[i]+1 == dist[p->v]) { pre[p->v] = i; path[p->v] = f2[i] = p; i = p->v; flag = true; break; } if (!flag) { dist[i] = -1; if (i == s) break; i = pre[i]; } } } return MaxFlow; } int main() { freopen("ditch.in", "r", stdin); freopen("ditch.out", "w", stdout); int i, u, v, w; for (i = 1; i <= V; i++) first[i] = NULL; for (i = 0; i < E; i++) { scanf("%d%d%d", &u, &v, &w); Insert(u, v, w); } printf("%d/n", Dinic(1, V)); return 0; }
Algorithm 2: PREFLOW algorithm
Algorithm 3: Edmonds Karp algorithm