原点s = 0,汇点t = 2 * n + 1,要把 cap[0][k]和cap[k + n][t] 设为INF,表示这几段的流量是无限制的。
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int N = 1000; const int INF = 0x3f3f3f3f; int n ,m; int cap[N][N],flow[N][N]; int p[N],a[N]; int maxflow(int s,int t) { int f = 0; queue<int> que; memset(flow,0,sizeof(flow)); while(true) { memset(a,0,sizeof(a)); a[s] = INF; que.push(s); while(!que.empty()) { int u = que.front(); que.pop(); for(int v = 1; v <= t; v++) { if(!a[v] && cap[u][v] > flow[u][v]) { //找到新节点v p[v] = u; que.push(v); a[v] = min(a[u],cap[u][v] - flow[u][v]); } } } if(a[t] == 0) { break; } for(int u = t; u != s; u = p[u]) { flow[p[u]][u] += a[t]; flow[u][p[u]] -= a[t]; } f += a[t]; } return f; } void init() { memset(cap,0,sizeof(cap)); memset(p,0,sizeof(p)); memset(a,0,sizeof(a)); } int main() { int tmp; while(scanf("%d",&n) != EOF) { init(); for(int i = 1; i <= n; i++) { scanf("%d",&tmp); cap[i][i+n] = tmp; } int u,v; scanf("%d",&m); for(int i = 1; i <= m; i++) { scanf("%d%d%d",&u,&v,&tmp); cap[u+n][v] = tmp; } int b,d; scanf("%d%d",&b,&d); for(int i = 1; i <= b; i++) { scanf("%d",&v); cap[0][v] = INF; } for(int i = 1; i <= d; i++) { scanf("%d",&u); cap[u+n][2*n+1] = INF; } int ans = maxflow(0,2*n+1); printf("%d\n",ans); } return 0; }