建立源点和汇点
S
和
1、对于所有的
1≤i≤m
,由源点
S
向第
2、对于所有的
3、对于所有的
这样,如果最大流等于所有单位的代表总数,那么有解,否则无解。
有解的情况下,如果第
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
inline int read() {
int res = 0; bool bo = 0; char c;
while (((c = getchar()) < '0' || c > '9') && c != '-');
if (c == '-') bo = 1; else res = c - 48;
while ((c = getchar()) >= '0' && c <= '9')
res = (res << 3) + (res << 1) + (c - 48);
return bo ? ~res + 1 : res;
}
const int N = 2e5 + 5, INF = 0x3f3f3f3f;
int m, n, ecnt = 1, nxt[N], adj[N], go[N], cap[N], len, que[N], a[N],
b[N], S, T, lev[N];
void add_edge(int u, int v, int w) {
nxt[++ecnt] = adj[u]; adj[u] = ecnt; go[ecnt] = v; cap[ecnt] = w;
nxt[++ecnt] = adj[v]; adj[v] = ecnt; go[ecnt] = u; cap[ecnt] = 0;
}
bool bfs() {
int i; for (i = S; i <= T; i++) lev[i] = -1;
lev[que[len = 1] = S] = 0;
for (i = 1; i <= len; i++) {
int u = que[i];
for (int e = adj[u], v; e; e = nxt[e])
if (cap[e] && lev[v = go[e]] == -1) {
lev[que[++len] = v] = lev[u] + 1;
if (v == T) return 1;
}
}
return 0;
}
int dinic(int u, int flow) {
if (u == T) return flow;
int res = 0, delta;
for (int e = adj[u], v; e; e = nxt[e])
if (cap[e] && lev[u] < lev[v = go[e]]) {
delta = dinic(v, min(cap[e], flow - res));
if (delta) {
cap[e] -= delta; cap[e ^ 1] += delta; res += delta;
if (res == flow) break;
}
}
if (res != flow) lev[u] = -1;
return res;
}
int maxflow() {
int res = 0;
while (bfs()) res += dinic(S, INF);
return res;
}
int main() {
int i, j, sum = 0; m = read(); n = read(); S = 1; T = m + n + 2;
for (i = 1; i <= m; i++) sum += (a[i] = read());
for (i = 1; i <= n; i++) b[i] = read();
for (i = 2; i <= m + 1; i++) add_edge(S, i, a[i - 1]);
for (i = m + 2; i < T; i++) add_edge(i, T, b[i - m - 1]);
for (i = 2; i <= m + 1; i++) for (j = m + 2; j < T; j++)
add_edge(i, j, 1); printf("%d\n", (j = maxflow()) == sum);
if (j != sum) return 0; for (i = 2; i <= m + 1; i++) {
for (int e = adj[i], v; e; e = nxt[e]) {
if ((e & 1) || (v = go[e]) == S || cap[e]) continue;
printf("%d ", v - m - 1);
}
printf("\n");
}
return 0;
}