有向無環圖 (DAG) 表示城市道路。飛機從起點飛到終點,每條路徑可覆蓋沿途城市。求最少飛機數覆蓋所有城市(每城市至少被一條路徑經過)。
DAG 中**最小不相交路徑覆蓋數** = |V| - 最大匹配數。
構造二分圖:
- 左部 U、右部 V 均為原圖頂點集合。
- 原圖邊 u→v → 二分圖邊 u(U) → v(V)。
最大匹配中每條匹配邊代表將兩條路徑合併(u 接 v)。
int n; vector G[MAXN];
int match[MAXN]; bool vis[MAXN];
bool dfs(int u) {
for (int v : G[u]) if (!vis[v]) {
vis[v] = true;
if (match[v]==-1 || dfs(match[v])) {
match[v] = u; return true;
}
}
return false;
}
int minPathCover() {
memset(match, -1, sizeof match);
int matchCnt = 0;
for (int u=1; u<=n; ++u) {
memset(vis, 0, sizeof vis);
if (dfs(u)) ++matchCnt;
}
return n - matchCnt;
}
O(V * E),V ≤ 100,E ≤ V^2,極快。
從未被匹配為右端點的頂點出發,沿匹配邊反向/正向追蹤構造路徑。