最近一直在写数论。。。。上课无聊学了一下网络流。。先刷一下这个水题吧。。。刚开始写了一个1s++效率非常低。。。只好借鉴被人的程序了。。。。。网络流第一次写。。。感觉这个算法很好的。。。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int map1[105][105], lev[105]; int que[300], iq; bool bfs(int s, int t) { int u, k, i; memset(lev, 0, sizeof (lev)); iq = 0, lev[s] = 1; que[iq++] = s; for (i = 0; i < iq; i++) { u = que[i]; if (u == t) return 1; for (k = 0; k <= t; k++) if (map1[u][k] > 0 && !lev[k]) { lev[k] = lev[u] + 1, que[iq++] = k; } } return 0; } int dinic(int s, int t) { int a[105], cur[105], pre[105]; int Mflow = 0, i, u, k, f, v; while (bfs(s, t)) { for (i = 0; i <= t; i++) // 初始化,回溯的时候找到cur,初始为0 cur[i] = 0, a[i] = INT_MAX; //a里是剩余流量 u = s; while (1) { for (v = cur[u]; v <= t; v++) if (map1[u][v] > 0 && lev[v] == lev[u] + 1) break; if (v <= t) { cur[u] = v + 1, pre[v] = u, a[v] = map1[u][v]; if (a[v] > a[u]) a[v] = a[u]; u = v; if (u == t) { f = a[t]; Mflow += f; for (v = t; v != s; v = pre[v]) { cur[pre[v]] = v; map1[pre[v]][v] -= f, map1[v][pre[v]] += f; a[v] -= f; if (map1[pre[v]][v] == 0) u = pre[v]; } } } else { if (u != s) lev[u] = INT_MAX, u = pre[u]; else break; } } } return Mflow; } int main() { int n, np, nc, m, i, j, u, v, w; while (scanf("%d%d%d%d", &n, &np, &nc, &m) != -1) { memset(map1, 0, sizeof (map1)); for (i = 1; i <= m; i++) { scanf(" (%d,%d)%d", &u, &v, &w); map1[u][v] = w; } for (i = 1; i <= np; i++) { scanf(" (%d)%d", &u, &w); map1[n][u] = w; } for (i = 1; i <= nc; i++) { scanf(" (%d)%d", &u, &w); map1[u][n + 1] = w; } printf("%d\n", dinic(n, n + 1)); } return 0; }