M 個豬圈(初始豬數),N 個顧客(持鑰匙集合、想買數量)。顧客按序到達,打開持鑰豬圈,賣豬後可在解鎖豬圈間重新分配。求最大銷售量。
M ≤ 1000, N ≤ 100。
S、匯點 T。INF(可任意重新分配)。// 讀入豬圈初始數 a[1..M]
// 處理每個顧客 i:
vector first(M+1, 0), last(M+1, 0);
for (int i = 1; i <= N; ++i) {
int A; cin >> A;
vector keys(A);
for (int k = 0; k < A; ++k) cin >> keys[k];
int B; cin >> B; // 購買上限
// 首次持鑰
for (int k : keys) {
if (!first[k]) { first[k] = i; addEdge(S, i, a[k]); }
else { addEdge(last[k], i, INF); }
last[k] = i;
}
if (B) addEdge(i, T, B);
}
cout << dinic(S, T) << endl;
N+2 ≤ 102,邊:O(N + M)。巧妙將「可重新分配」建模為時序上相鄰持鑰顧客間的無限容量邊,將豬圈初始存量從源點注入首個持鑰者,購買上限作為顧客到匯點容量。標準最大流模板即可解決。