Flow problem
Time limit:5000/5000 MS (java/others) Memory limit:65535/32768 K (java/others)
Total Submission (s): 9423 Accepted Submission (s): 4405
problem DescriptionNetwork Flow is a well-known difficult problem for acmers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.
Inputthe first line of input contains an integer T, denoting the number of the test cases.
For each test case, the first line contains integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <=, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is a edge from X to Y and the capacity of it is C. (1 & lt;= X, Y <= N, 1 <= C <=)
Outputfor each test cases, you should the output of the maximum flow from source 1 to sink N.
Sample Input
23 21 2 12 3 13 31 2 12 3 11 3 1
Sample Output
Case 1:1case 2:2
Title Link: http://acm.hdu.edu.cn/showproblem.php?pid=3549
The main idea: is to find the source point of 1, meeting point is N network maximum flow
Title Analysis: Blog before have written a few of the biggest flow of the topic, but with the EK algorithm, EK This algorithm can be eliminated, because of its time complexity is too high, this problem with EK to 2000ms+,ek algorithm is not affixed, the following main mentioned in SAP two mainstream algorithm, Dinic and ISAP algorithm, the two algorithms in solving the problem on the time is quite, are about 150ms, but in fact ISAP efficiency is higher than dinic, about Dinic and ISAP algorithm introduction will be in other articles, here on the template
Dinic 1: Hidden Level network
#include <cstdio> #include <cstring> #include <queue> #include <algorithm>using namespace std; int const MAX = 16;int Const INF = 0x3fffffff;int cap[max][max];int d[max];int N, m;bool BFS () {memset (d, 0, sizeof (d)) ; Queue <int> Q; D[1] = 0; Q.push (1); while (! Q.empty ()) {int cur = q.front (); Q.pop (); for (int i = 2; I <= n; i++) {if (Cap[cur][i] > 0 && d[i] = = 0) { D[i] = D[cur] + 1; Q.push (i); }}} return d[n];} int dinic (int t, int flow) {if (t = = n) return flow; int tmp = flow; for (int i = 1; I <= n; i++) {if (d[i] = = D[t] + 1 && cap[t][i] > 0) {int mi = d Inic (i, min (flow, cap[t][i])); Cap[t][i]-= mi; Cap[i][t] + = mi; Flow-= mi; }} return tmp-flow;} int main () {int T; scanf ("%d", &t); for (int CA = 1; CA &lT;= T; ca++) {memset (cap, 0, sizeof (CAP)); scanf ("%d%d", &n, &m); for (int i = 0; i < m; i++) {int u, V, W; scanf ("%d%d%d", &u, &v, &w); CAP[U][V] + = W; } int ans = 0; while (BFS ()) ans + = dinic (1, INF); printf ("Case%d:%d\n", CA, ans); }}
Dinic 2: dominant Hierarchical network
#include <cstdio> #include <cstring> #include <queue> #include <algorithm>using namespace std; int const MAX = 20;int Const INF = 0x3fffffff;int Cap[max][max];bool Sign[max][max], Vis[max];int d[max];int N, M;bool BFS () {memset (Vis, false, sizeof (VIS)); Memset (sign, false, sizeof); Queue <int> Q; D[1] = 0; Q.push (1); while (! Q.empty ()) {int cur = q.front (); Q.pop (); for (int i = 2; I <= n; i++) {if (!vis[i] && cap[cur][i]) {Vis[i] = True Sign[cur][i] = true; Q.push (i); }}} return vis[n];} int dinic (int t, int flow) {if (t = = n) return flow; int tmp = flow; for (int i = 2; I <= n; i++) {if (Sign[t][i]) {int mi = dinic (i, min (flow, cap[t][i])); Cap[t][i]-= mi; Cap[i][t] + = mi; Flow-= mi; }} return tmp-flow;} int main () {int T; scanf ("%d", &t); for (int CA = 1; CA <= T; ca++) {memset (cap, 0, sizeof (CAP)); scanf ("%d%d", &n, &m); for (int i = 0; i < m; i++) {int u, V, W; scanf ("%d%d%d", &u, &v, &w); CAP[U][V] + = W; } int ans = 0; while (BFS ()) ans + = dinic (1, INF); printf ("Case%d:%d\n", CA, ans); }}
Isap:
#include <cstdio> #include <queue> #include <cstring> #include <algorithm>using namespace std; int const INF = 0x3fffffff;int Const MAXN = 2000;int Const MAXM = 2000;int HEAD[MAXN], GAP[MAXN], D[MAXN], CUR[MAXN], pre[ Maxn];int N, m, e_cnt;struct edge{int to, cap, flow, next;} e[maxm];void Add_edge (int u, int v, int cap) {e[e_cnt].to = v; E[e_cnt].cap = cap; E[e_cnt].flow = 0; E[e_cnt].next = Head[u]; Head[u] = e_cnt + +; e[e_cnt].to = u; E[e_cnt].cap = 0; E[e_cnt].flow = 0; E[e_cnt].next = Head[v]; HEAD[V] = e_cnt + +;} void BFS (int t) {queue <int> Q; memset (Gap, 0, sizeof (GAP)); memset (d,-1, sizeof (d)); D[t] = 0; Q.push (t); while (! Q.empty ()) {int v = q.front (); Q.pop (); GAP[D[V]] + +; for (int i = head[v]; i =-1; i = e[i].next) {int u = e[i].to; if (d[u] = = 1) {D[u] = D[v] + 1; Q.push (U); }}}}int ISAP (int s, int t) {BFS (t); int ans = 0, U = s, flow = INF; memcpy (cur, head, sizeof (cur)); while (D[s] < e_cnt) {int i = cur[u]; for (; I! =-1; i = e[i].next) {int v = e[i].to; if (E[i].cap > E[i].flow && d[u] = = D[v] + 1) {u = V; PRE[V] = i; flow = min (flow, e[i].cap-e[i].flow); if (U = = t) {while (U = s) {int j = Pre[u]; E[j].flow + = flow; e[j ^ 1].flow-= flow; U = e[j ^ 1].to; } ans + = flow; flow = INF; } break; }} if (i = =-1) {if (---gap[d[u]] = = 0) break; int mi = e_cnt-1; Cur[u] = Head[u]; for (int j =Head[u]; J! =-1; j = e[j].next) if (E[j].cap > E[j].flow) mi = min (mi, d[e[j].to]); D[u] = mi + 1; Gap[d[u]] + +; if (U = s) u = e[pre[u] ^ 1].to; }} return ans; int main () {int T, ans; scanf ("%d", &t); for (int CA = 1; CA <= T; ca++) {scanf ("%d%d", &n, &m); e_cnt = 0; Memset (Head,-1, sizeof (head)); for (int i = 0; i < m; i++) {int u, V, W; scanf ("%d%d%d", &u, &v, &w); Add_edge (U, V, W); } ans = ISAP (1, N); printf ("Case%d:%d\n", CA, ans); }}
HDU 3549 Flow problem (the way to open the network stream algorithm with one of the bare maximum flows)