#include <stdio.h> #include <string.h> #define DEBUG #ifdef DEBUG #define debug(...) printf( __VA_ARGS__) #else #define debug(...) #endif #define N 102 #define MAX_INT 2000000 #define min(a, b) ((a) < (b) ? (a) : (b)) int graph[N][N]; int h[N]; int e[N]; int n; int push_relabel(int s, int t) { int max_flow, u, v, d, done, relabel, min_height; memset(h, 0, sizeof(h)); memset(e, 0, sizeof(e)); h[s] = n; for (u = 1; u <= t; u++) { if (graph[s][u] > 0) { e[u] = graph[s][u]; e[s] -= graph[s][u]; graph[u][s] = graph[s][u]; graph[s][u] = 0; } } for (;;) { done = 1; for (u = s+1; u < t; u++) { if (e[u] > 0) { done = 0; //先假设顶点u需要relabel relabel = 1; for (v = s; v <= t && e[u] > 0; v++) { /* 检查能push的顶点 */ if (graph[u][v] > 0 && h[u] > h[v]) { //push relabel = 0; d = min(graph[u][v], e[u]); e[u] -= d; e[v] += d; graph[u][v] -= d; graph[v][u] += d; debug("push %d --%d--> %d, e[%d] = %d\n", u, d, u, u, e[u]); } } //没有可以push的顶点,执行relabel if (relabel) { //relabel min_height = MAX_INT; for (v = s; v <= t; v++) { if (graph[u][v] > 0 && h[v] < min_height) { min_height = h[v]; } } h[u] = 1 + min_height; debug("relabel %d height to %d\n", u, h[u]); } } } if (done) { /* 除源点和汇点外,每个顶点的e[i]都为0 */ max_flow = 0; for (u = s; u <= t; u++) { if (graph[t][u] > 0) { max_flow += graph[t][u]; } } break; } } return max_flow; } int main() { int np, nc, m, u, v, w; while (scanf("%d", &n) != EOF) { n += 2; /* 添加源点和汇点 */ scanf("%d %d %d", &np, &nc, &m); memset(graph, 0, sizeof(graph)); //输入m条边 while (m--) { scanf(" (%d,%d)%d", &u, &v, &w); graph[u+1][v+1] = w; } //输入np个power station while (np--) { scanf(" (%d)%d", &u, &w); graph[0][u+1] = w; } //输入nc个consumer while (nc--) { scanf(" (%d)%d", &u, &w); graph[u+1][n-1] = w; } printf("%d\n", push_relabel(0, n-1)); } return 0; }