#include <cstdio> #include <queue> #include <cstring> using namespace std; int n, np, nc, m, i, start, end; int network[103][103];//残余网络 int level[103]; bool bfs()//广度优先搜索只负责标记层次号,即该节点与源节点的最短距离 { queue<int> q; memset(level, -1, sizeof(level)); level[start] = 0; q.push(start); while (!q.empty()) { int v = q.front(); q.pop(); for (int i = 0; i < n+2; i++) { if (network[v][i] && level[i] == -1) { level[i] = level[v] + 1;// update the level q.push(i); } } } return (level[end] != -1); } int dinic() { int max = 0; int path[103], pos; while (bfs()) {//存在源点到目的点的路径 int v = start; pos = 0; path[pos++] = start; for (;;) { if (v == end) {//找到可扩路 int maxf = 10001, k = 0; for (int i = 0; i < pos - 1; i++) {//找到该路上的可扩容量 if (maxf > network[path[i]][path[i+1]]) { maxf = network[path[i]][path[i+1]]; k = i; } } max += maxf; for (int i = 0; i < pos - 1; i++) {//更新残余网络 network[path[i]][path[i+1]] -= maxf; network[path[i+1]][path[i]] += maxf; } pos = k + 1;//找到前一个可以继续深度搜索的节点,不要重新从源点开始 v = path[pos-1]; } int k; for (k = 0; k < n+2; k++) { if (network[v][k] && level[k] == level[v]+1) { path[pos++] = k; break; } } if (k >= n+2) { if (--pos == 0)//退出深度搜索 break; level[path[pos]] = -1; } v = path[pos-1]; } } return max; } int main() { char str[20]; while (scanf("%d", &n) != EOF) { scanf("%d%d%d", &np, &nc, &m); memset(network, 0, sizeof(network)); start = n; end = n + 1; for (i = 0; i < m; i++) { int s, e, v; scanf("%s", str); sscanf(str, "(%d,%d)%d", &s, &e, &v); network[s][e] += v; } for (i = 0; i < np; i++) { int node, value; scanf("%s", str); sscanf(str, "(%d)%d", &node, &value); network[start][node] += value; } for (i = 0; i < nc; i++) { int node, value; scanf("%s", str); sscanf(str, "(%d)%d", &node, &value); network[node][end] += value; } printf("%d/n", dinic()); } return 0; } dinic算法比ek算法快,关键地方在于dinic算法减少了查找可扩路得次数.