有向圖 N 個島嶼(節點),M 條橋(邊),每條邊有摧毀成本。國家 1(源點)攻擊國家 N(匯點),國家 N 想以最小總成本切斷所有 1→N 路徑。國家 1 可在戰前做一件事:新建一條不可摧毀的有向邊(端點在 2..N-1),或將現有邊升級為不可摧毀。求國家 1 能強迫國家 N 支付的最大可能最小摧毀成本。
ans0。INF(不可切割),再在殘量網絡上跑最大流,得到額外增加的流量 Δ。INF,在殘量圖上繼續增廣,記錄最大增量 maxΔ。ans0 + maxΔ。ans0 並保存殘量網絡。u∈S, v∈T, cap>0 的原邊:臨時將容量設為 INF,在殘量圖上繼續跑最大流得增量,還原容量,取最大增量。ans0 + maxΔ。struct Edge { int to, next, cap, flow; };
vector<Edge> edges;
vector<int> head, cur, dep, gap, pre;
void addEdge(int u, int v, int w) {
edges.push_back({v, head[u], w, 0});
head[u] = edges.size() - 1;
edges.push_back({u, head[v], 0, 0});
head[v] = edges.size() - 1;
}
int sap(int s, int t, int n) {
// 標準 SAP 實現,返回最大流
// 並保留 dep, gap, cur, pre 等輔助數組以便後續增廣
}
int main() {
int T; scanf("%d", &T);
while (T--) {
int n, m; scanf("%d%d", &n, &m);
init();
for (int i=0;iedges[i].flow && !inS[v]){
inS[v]=1; q.push(v);
}
}
}
int maxAdd = 0;
// 枚舉割邊
for(int i=0;i0){
int oldCap = edges[i].cap;
edges[i].cap = INF;
int add = sap(1, n, n);
maxAdd = max(maxAdd, add);
edges[i].cap = oldCap;
// 還原流量狀態(或重新建圖更簡單)
}
}
printf("%d\n", base + maxAdd);
}
}
N ≤ 100,M ≤ 4950,重建圖 + 重跑流完全在時限內。