或許只是一個非常簡單的題目類型,但是我智商太低,花了好久才理解這類模型之間的關聯。
所以簡單總結一下,歡迎指出錯誤。
原版問題
問題 1:給定一張 \(\text{DAG}\),需要選出最少的路徑,覆蓋所有點,路徑不可有交。
這里直接給出做法:將每個點 \(u\) 拆成左部點 \(u\) 和右部點 \(u'\),對於原圖中的一條邊 \((u,v)\),在新圖中連接 \((u,v')\)。之后新建源匯,連接所有 \((S,i)\),\((i',T)\),則最小路徑覆蓋 \(=n-maxflow\)。
藍書上的理解方式是二分圖最大匹配,這里之所以直接寫作最大流,是為了更好地擴展到必須使用網絡流算法求解的其他變種。
事實上,如果從“匹配”的角度來理解,那么一對匹配點的本質即為選出了某條路徑上的一條邊。對於未匹配點,未匹配的一個右側點代表一條所選路徑的起點,左端點代表終點。
因此一種天然的構造答案方式是:找出所有未匹配的右側點,然后順着往下把路徑找出來即可。
這個經典問題可以被視為一類模型極其特殊的例子:對於給定的 \(\text{DAG}\),選出一些路徑,覆蓋所有點。而在這個特例中,每條邊費用均為 \(0\),每個點選擇次數均恰好為 \(1\)。正是因為有這兩個條件,我們才可以用“\(n-maxflow\)"計算最小路徑覆蓋。
問題 2:給定一張 \(\text{DAG}\),需要選出最少的路徑,覆蓋所有點,允許路徑相交。
對原圖進行傳遞閉包之后就可以轉化為上一個問題。
下面總結該問題的幾種變式。這幾種變式在原版的基礎上對一些條件進行了限制。
變式 1:邊帶權與起點代價
“瞬間移動”的本質即在經典問題的基礎上增加了起點選取的代價。
考慮經典問題的建模方式。\(S\to u\) 的邊本質上代表了 \(u\) 不是某條路徑的起點,也就是說到達 \(u\) 的方式是“從某條路徑走過來”。
那么我們同樣連邊 \(S\to u'\),含義為點 \(u\) 的到達方式為“作為起點到達”。
再來考慮“邊帶權”的問題。類比普通二分圖匹配與二分圖帶權匹配的關系,經典問題帶權后,我們將最大流改為最小費用最大流即可。
另外,這種變式存在另一種理解方式(最小費用可行流),參見洛谷題解區 zyb 的題解。我沒有細看,不知道這種理解方式能不能推廣到其他幾種變式。
變式 2:限制路徑條數
如果沒有路徑條數限制,那么本題與變式 1 完全一致。
處理方式也很簡單:建一個新點 \(S'\),連邊\(S\to S'\),容量為 \(K\)。接着將所有 \(S\to u'\) 全部改為 \(S'\to u'\)。
不過在這道題中,我們沒有必要特意將 \(S'\) 建出,只需要讓 \(0\) 號點承擔 \(S'\) 的功能即可。
變式 3:多次覆蓋,限制結點覆蓋次數
所謂的“快洗”“慢洗”本質上就是從 \(u\) 向所有 \([u+m,N]\) 的 \(v'\) 連邊,因此這仍然是一個路徑覆蓋問題。
大部分題解的理解角度是拆成“早上”“晚上”,如果從路徑覆蓋的視角理解這種建模方式,“晚上”就是路徑覆蓋的左部點,“早上”是右部點。
每個點覆蓋次數有下限無上限,但顯然最優方案下每個點覆蓋次數都等於這個下限。
類比普通二分圖匹配與二分圖多重匹配的關系,修改 \(S\to u,u'\to T\) 的容量即可。
另外,在題解區的一些代碼中,左部點集出現了順次向后連邊的情況,這似乎與我們最初建立的二分圖匹配模型並不一致。這種現象出現的原因是,如果按照套路建邊(\(u\to v',v\in[u+m,N]\)),邊數將會非常多,不可接受。由於本題中左、右部點間的邊容量均為 \(+\infty\),費用均為 \(0\),我們可以采取這種方式減少邊數。
邊數有限,多次覆蓋,每個點覆蓋次數欽定。
有關邊數的問題這里不再討論,參見變式 \(2\)。
本題中每個點覆蓋次數同時存在上下限且相等。我們將 \(S'\to u,u'\to T\) 的容量同時修改為限制即可。
對於覆蓋次數只有上限的問題,我還沒做到過,不過我估摸着類似地改改邊權就行了。
變式 4:限制路徑數,求最多覆蓋點數
依照原題給出的限制和關系,我們不難將數字間的匹配關系建成一張 \(\text{DAG}\)。下面我們要依次覆蓋這張 \(\text{DAG}\) 中的點。
一種比較暴力的思路是,二分答案,然后直接建圖跑經典模型。
但顯然這樣做的時間開銷是極大的,不可取。
發現隨着覆蓋點數的增加,需要的路徑數單調不增。因此考慮動態地建出這張圖。
具體地,我們從小到大一個個加入新點並建邊,然后尋找增廣路。如果找不到增廣路,說明必須增加一條路徑。
