上下界最大流模板
虽然不知道为什么……
C++ code:
#include <iostream> #include <cstdio> #include <cstring> #define MAXN 200 #define inf 1000000000 using namespace std; int limit_max_flow(int, int [][MAXN], int [][MAXN], int, int, int [][MAXN]); void _max_flow(int, int [][MAXN], int, int, int [][MAXN]); int main() { int n, m, mat[200][200], bf[200][200], flow[200][200], i, k, j, ID, G, U, D, p, q; while(scanf("%d%d", &n, &m) == 2) { memset(mat, 0, sizeof(mat)); memset(bf, 0, sizeof(bf)); memset(flow, 0, sizeof(flow)); for(i = 1; i <= n; i++) { scanf("%d", &k); for(j = 1; j <= k; j++) { scanf("%d", &ID); mat[n + ID][i] = 1; } } for(i = 1; i <= m; i++) { scanf("%d", &U); mat[0][n + i] = U; } for(i = 1; i <= m; i++) { scanf("%d", &D); bf[0][n + i] = D; } scanf("%d", &G); for(i = 1; i <= G; i++) { scanf("%d", &p); for(j = 1; j <= p; j++) { scanf("%d", &q); for(k = 1; k <= m; k++) if(mat[n + k][q]) { mat[n + k][q] = 0; mat[n + k][n + m + i] = mat[n + m + i][q] = 1; } } } for(i = 1; i <= n; i++) mat[i][n + m + G + 1] = 1; printf("%d\n", limit_max_flow(n + m + G + 2, mat, bf, 0, n + m + G + 1, flow)); } return 0; } int limit_max_flow(int n, int mat[][MAXN], int bf[][MAXN], int source, int sink, int flow[][MAXN]) { int i, j, sk, ks; if(source==sink) return inf; for(mat[n][n + 1] = mat[n + 1][n] = mat[n][n] = mat[n+1][n+1] = i = 0; i < n; i++) for(mat[n][i] = mat[i][n] = mat[n + 1][i] = mat[i][n + 1] = j = 0; j < n; j++) { mat[i][j] -= bf[i][j]; mat[n][i] += bf[j][i]; mat[i][n + 1] += bf[i][j]; } sk = mat[source][sink]; ks = mat[sink][source]; mat[source][sink] = mat[sink][source] = inf; for(i = 0; i < n + 2; i++) for(j = 0; j < n + 2; flow[i][j++] = 0); _max_flow(n + 2, mat, n, n + 1, flow); for(i = 0; i < n; i++) if(flow[n][i] < mat[n][i]) return -1; flow[source][sink] = flow[sink][source] = 0; mat[source][sink] = sk; mat[sink][source] = ks; _max_flow(n, mat, source, sink, flow); for(i = 0; i < n; i++) for(j = 0; j < n; j++) { mat[i][j] += bf[i][j]; flow[i][j] += bf[i][j]; } for(i = j = 0; i < n; j += flow[source][i++]); return j; } void _max_flow(int n, int mat[][MAXN], int source, int sink, int flow[][MAXN]) { int pre[MAXN], que[MAXN], d[MAXN], p, q, t, i, j; for(;;) { for (i=0;i<n;pre[i++]=0); pre[t = source] = source + 1; d[t] = inf; for(p = q = 0; p <= q && !pre[sink]; t = que[p++]) for(i = 0; i < n; i++) if(!pre[i] && (j = mat[t][i] - flow[t][i])) { pre[que[q++] = i] = t + 1; d[i] = d[t] < j ? d[t] : j; } else if(!pre[i] && (j = flow[i][t])) { pre[que[q++] = i] = -t - 1; d[i] = d[t] < j ? d[t] : j; } if(!pre[sink]) break; for(i = sink; i != source;) if(pre[i] > 0) { flow[pre[i] - 1][i] += d[sink]; i = pre[i] - 1; } else { flow[i][-pre[i] - 1] -= d[sink]; i = -pre[i] - 1; } } }