前言
貌似並不知道要說什麼(?)
哦,對了,我謝謝你@陳二喜。
(一)P3358 最長 $k$ 重區間集問題
題意:給定 $n$ 個左閉右開的區間,從這些區間中選取一些區間,使得數軸上沒有任何一個點被超過 $k$ 個區間包含,並使得區間覆蓋長度最大。
題意沒給 $l,r$ 範圍,先離散化。
先找流量和費用。首先有一個【每個區間只能選擇一次】的隱性條件限制。可以想到將次數作為流量,顯然長度就作為花費。
那麼怎麼表示選擇一個區間呢?我們可以將區間左端點連向右端點,流量為 $1$,費用該區間的長度。
一點最多選 $k$ 次,那麼我們對於數軸上每一個點 $i$ 連向 $i+1$,容量為 $k$,費用為 $0$。
跑一邊最大費用最大流即可。
(二)P4014 分配問題
題意:$n$ 個工件分給 $n$ 個工人,第 $i$ 個人做第 $j$ 個工件的效益為 $c_{i,j}$,求問在一個零件只能匹配一個工人,並且一個工人只能加工一個零件的情況下,效益最大是多少。
顯然有一個二分圖的模型,把工人放到左邊,零件放到右邊。中間是若干邊。
很套路的,建立一個虛擬源點 $s$,連向每一個工人,容量為 $1$,費用為 $0$,表示一個工人只能匹配一個,沒有匹配零件所以沒有費用。
同樣,建立一個虛擬匯點 $t$,每一個零件連向匯點,容量為 $1$,費用為 $0$。
之後對於第 $i$ 個工人和第 $j$ 個零件連一條容量為 $1$,費用為 $c_{i,j}$ 的邊,表示一個工人和一個零件只能匹配一次,獲得的價值為 $c_{i,j}$。
要使效益最大,最後跑一邊最大費用最大流。
(三)P2774 方格取數問題
題意:$m\times n$ 的方格,每個方格有一個數,選取若干的數,使得任意兩個選取的數在方格中沒有公共邊,求最大和。
直接做不好做,考慮假設我們選取的了所有的數,那麼現在我們要求最少刪掉的代價。
這樣就很像最小割了。
我們對於圖黑白染色,若 $(i+j)\bmod 2=1$,則該點為黑,否則為白。
建立虛擬源點 $s$,和虛擬匯點 $t$。我們令 $s$ 連向每一個黑點,容量為點權。每一個白點連向 $t$,容量同樣為點權。表示我們刪去這個點需要的價值。
我們將每個黑點連向與它四聯通的白點,容量為無限大。
根據最大流 = 最小割,跑一遍最大流就行了。
為什麼這樣做是對的,性感理解一下。但考慮一張 $s\to u\to u'\to t$ 的圖,我們跑最大流肯定是在 $s\to u$ 和 $u'\to t$ 這兩條邊之間取的最小值,因為如果取了最大值就會超過另一條邊的容量。這也就是求得刪去的數的最小值。邊權為 $\infty$ 表示這兩個點見只能選擇一個,因為最小割肯定不會割掉邊權為 $\infty$ 的邊。
最後有所有點的總和減去最小割即可。
(四)P4015 運輸問題
題意:單位 $i$ 有 $a_i$ 單位的貨物,商店 $j$ 有 $b_j$ 的貨物需求量,保證 $\sum a_i=\sum b_j$。第 $i$ 個單位運到第 $j$ 個商店需要花費 $c_{i,j}$ 的代價,求最小和最大費用。
看出這是一個二分圖模型,把單位放到左邊,商店放到右邊。
很顯然是個費用流。貨物量就是流量,代價就是費用。因為題目中保證 $\sum a_i=\sum b_j$,所以想到源點流出的流量等於匯點接受的流量。
建立虛擬源點 $s$ 和虛擬匯點 $t$,$s$ 連向每一個單位,容量為該單位的貨物量,費用為 $0$。每一個商店連向 $t$,流量為該商店的需求量,費用為 $0$。
最後對於每一個單位連向每一個商店,容量無限大,費用就是那個代價。
最後跑一次最小費用最大流和一次最大費用最大流即可。
(五)P2762 太空飛行計劃問題
題意:有 $m$ 個實驗。每個實驗只能進行一次,但會獲得相應的獎金,有 $n$ 個儀器,每個實驗都需要一定的儀器,每個儀器可以應用於多個實驗,但需要一定的價值,問獎金與代價的差的最大值是多少?輸出方案。
我們假設選擇了所有實驗,但所有的儀器先不選,然後找到一個花費最小的方案去掉若干個實驗。
這就像最小割了。跟方格取數問題一樣。
我們建立虛擬源點 $s$ 和虛擬匯點 $t$,然後 $s$ 連向每一個實驗,流量為獎金,每一個零件連向 $t$,容量為花費。
求最小割,就相當於跑最大流。
怎麼解釋這件事情。考慮我們一開始求得獎金總和,假設我們割掉了某一個儀器,那麼就相當於這個儀器不選,恰好減去他的獎金。如果割掉了某個零件,就相當於選了這個零件,同樣花費了它的代價。
至於輸出方案,有一個結論,在最後一次 $\text{Dinic}$ 中,被分到層上點都不會被割掉。
性感證明一下:我們在選擇從 $s$ 到儀器的邊中,最後一次肯定會選擇滿流的點,而那些沒有滿流的點都是被割掉的。然後會對那些滿流的節點分層,最後只需判斷一下一個點是否分了層即可。
(六)P2770 航空路線問題
題意:從西到東有 $n$ 個城市,$m$ 個航線,每個航線單向連線兩個城市。求從最西的城市到最東的城市再回最西城市,除最西和最東城市每個城市只經過一次情況下,經過城市數最多,並輸出方案。
首先可以得出一些性質:考慮來回一趟的旅程就相當於從起點到終點兩趟,兩次不經過相同的城市。【每一個城市只能遍歷一次】的條件說明每一條航線也只能遍歷一次。
【每一個城市只能經過一次】這一限制條件很套路,將每一個城市拆成兩個點,一個入點 $u$ 和一個出點 $u'$,我們連從 $u$ 到 $u'$ 容量為 $1$ 的邊,表示這個點只能經過一次,而題目又要使得經過城市數儘量多,所以可以看出是最大費用最大流的問題,我們讓 $u$ 到 $u'$ 的費用為 $1$,表示經過了一個城市。
之後對於每一條航線,根據一開始推出的每條航線只能經過一次,我們對於每一條航線 $(x,y)$,從 $x'$ 到 $y$ 連一條容量為 $1$,費用為 $0$ 的邊。
最後跑最大費用最大流即可。
輸出方案仍然很簡單,網路流有一個性質就是,流量為 $0$ 的邊一定是被選上的。那麼我們從起點開始 $dfs$,每一次找邊權為 $0$ 的邊暴搜下去。然後搜兩次,第二次反著輸出,因為是返程。
(七)P2754 星際轉移問題
題意:有 $n$ 個太空站,容量無限,$m$ 艘飛船,每艘船有容量 $h_i$,第 $i$ 搜飛船會週期性的停靠太空站,$k$ 個人在地球 $0$,要使所有人都飛往月球,最快需要多少時間。
考慮按時間分層的 $\texttt{trick}$。
我們列舉答案 $T$,那麼我們對於每一個船在 $T-1$ 時刻所到達的星球與 $T$ 時刻所到達的星球連一條容量為 $h_i$,表示最多裝 $h_i$ 的人。
當然,上一個時刻的每一個空間的人都可以停留,那麼我們將每一個星球上一個時刻和這一個時刻連一條容量為 $\infty$ 的邊,表示這個空間站的容量是無限大的。
特殊的,我們建立虛擬源點 $s$ 和虛擬匯點 $t$,我們將 $s$ 連向地球,容量無限大,月球連向 $t$,容量也為無限大。
對於每一個時刻都跑最大流,直到最大流不小於 $k$ 為止,說明可以載夠 $k$ 個人了。
判斷無解考慮並查集即可。
(八)P3254 圓桌問題
題意:$m$ 個單位,第 $i$ 個單位派出了 $r_i$ 個代表。有 $n$ 個桌子,第 $i$ 個桌子可以容納 $c_i$ 人,要求同一個單位的代表不能做相同桌子,求一個合法方案。
不難看出這也是一個二分圖模型,把單位放在左邊,桌子放在右邊。
我們先建立虛擬源點 $s$,讓 $s$ 連線每一個單位,容量為改單位的代表人數,表示一個單位的初始人數,我們想讓這些人都不在同一個餐桌,那麼就可以通過流量來起限制作用,我們將每一個單位向每一個餐桌連線一條流量為 $1$ 的邊,表示該單位只能對該桌派出一個代表。而餐桌也是有名額限制的,我們將每一個餐桌向虛擬匯點 $t$ 連一條容量為 $c_i$ 的邊。
如何判斷無解,充要條件是源點的流出量必須等於匯點的接收量。
那麼如何判斷每一個人都坐在哪些位置呢?還是判斷每一條邊的流量是否為 $0$,即可找到每一個人坐到了哪一個餐桌。
(九)P1251 餐巾計劃問題
題意:有 $n$ 天,每一天會需要 $r_i$ 個毛巾。可以直接購買新毛巾,或將現有毛巾送到慢洗部或快洗部花一定的錢洗若干天。毛巾用一天就會髒。求最小花費。
我們發現並沒有很顯然的二分圖模型,但發現有【毛巾用一天就會髒】這一條件,提示我們按照【白天】和【黑夜】分層。
我們對於每一天構建兩個點,一個黑天一個白天。我們將黑天放左邊,白天放右邊。
我們知道,每一天的 $r_i$ 個毛巾是必須要滿足要求的,那麼我們可以把毛巾需求量作為流量。而題目又要使花費最小,不難發現是一道最小費用最大流的問題。
我們建立虛擬源點 $s$,我們將 $s$ 向每一個黑天連容量為 $r_i$,費用為 $0$ 的邊。表示獲取這麼多的髒毛巾。
同樣,我們建立虛擬匯點 $t$,我們將每一個白天向 $t$ 連容量為 $r_i$,費用為 $0$ 的邊,表示當天用了這些乾淨的毛巾。
現在考慮怎樣將從源點獲取的髒毛巾轉變為乾淨的毛巾。
最直接的是買毛巾。直接從源點獲取。向白天連一條容量無限大,費用為每塊餐巾的費用。
之後就是快洗和慢洗的問題了,將當天晚上連向洗完那天的白天,容量為無限大,費用為快洗或慢洗的花費。
還有一個小坑,就是當天的髒毛巾可以拖到明天,或是更遠幾天再洗,那麼我們將每一天晚上連向第二天晚上一個容量為無限大費用為 $0$ 的邊。
跑一遍最小費用最大流即可。
(十)P2763 試題庫問題
題意:有 $n$ 個試題,每個題有若干個 $\texttt{tag}$,要抽取 $m$ 個道題組成的試卷,型別 $i$ 的試題需要 $a_i$ 個。求一個合法的試卷組合。
這也有一個二分圖模型,左邊是試題,右邊是型別。
由於一個試題只能用一次,那麼我們從源點向每一個試題連一個容量為 $1$ 的邊。
而當我們選擇一個試題之後,就會獲得一些 $\texttt{tag}$,那麼我們將每一個試題向它的每一個型別連一條容量為 $1$ 的邊,最後每一個型別向匯點 $t$ 連容量為 $a_i$ 的邊。表示 $i$ 型別的題需要 $a_i$。
最後跑一遍最大流。
輸出的方法還是一樣,找流量為 $0$ 的邊就行了。
(十一)P2766 最長不下降子序列問題
題意:給定長度為 $n$ 的數列,求:①最長不下降子序列的長度 $s$;②每一個元素只能使用一次的情況下,最多可以取出多少個長度為 $s$ 的不下降子序列;③若 $a_1$ 和 $a_n$ 可以使用多次,最多可以取出多少個長度為 $s$ 的不下降子序列。
第一問直接 dp,並記錄最長不下降子序列的長度 $F$ 和 $dp_i$,表示以 $i$ 為結尾的最長不下降子序列的長度。
考慮二三問。
首先發現每個元素只能使用一次,那麼套路的,我們對於每一個元素拆點,中間的流量為 $1$,表示只用一次。
然後列舉 $dp$ 值為 $1$ 的位置,這種位置只能放在開頭,那麼我們將 $s$ 向它連一條容量為 $1$ 的邊。
同理,再列舉 $dp$ 值為 $F$ 的點,這種點只能放在結尾,所以我們將它連向 $t$,容量為 $1$。
然後考慮把 $s$ 和 $t$ 關聯起來,很容易想到,$dp$ 值其實就相當於一個分層操作,對於兩個點 $i,j$,如果 $a_i\ge a_j$ 且 $dp_i=dp_j+1$,那麼說明 $j$ 可以轉移到 $i$,我們將 $j$ 到 $i$ 連一條容量為 $1$ 的邊。
跑一遍最大流就是第二問的答案。
第三問也很簡單,我們將 $s$ 到 $1$ 和 $1$ 到它的拆出來的點的流量都改成無窮大。
但是隻有在 $dp_n=F$ 的情況下我們才更改 $n$ 到 $n$ 對應的拆出來的點,和拆出來的點到 $t$ 的流量。這是一個小坑。
最大流即可。
(十二)P3355 騎士共存問題
題意:在 $n\times n$ 的棋盤上放置馬,使得任意兩個馬不攻擊,有 $m$ 個給定的位置不能放,求最多放幾個馬。
雖然不能說跟剛剛的方格取數問題一模一樣,但也是很類似了。
同樣假設取了所有點,然後最小化減少矛盾的馬的數量就是最大化答案。
這樣對原圖黑白染色,然後跑最小割即可。
(十三)P4013 數字梯形問題
題意:給定一個數字梯形,從最頂端開始走 $m$ 條路徑,每次朝左下或右下走,三問(一)路徑不能相交(二)只能在節點處相交(三)可以在節點或邊相交。
我們發現起點有 $m$ 個,是分散的,不如先建立 $s$ 連向第一行的每個數。然後最後一行的每一個點連向 $t$。容量 $1$,費用 $0$。
先考慮第一問,發現又有節點只能經過一次的限制。直接拆點,中間連容量為 $1$,費用為該節點的權的邊。
然後每一個點的出點連向下面一行左邊和右邊的點,容量為 $1$,費用為 $0$。因為邊也只能經過一次。
對於第二問,我們直接將每個點的入點和出點的容量改為 $\infty$,表示每個點可以經過無限次。有一個小坑就是最下面一行的每一個點連向 $t$ 的容量也都改為 $\infty$,因為某一條路徑到達最下面的某一個點後,已經結束了,所以跟到終點的容量沒有關係。
對於第三問,除了 $s$ 到第一行每一個點的邊以外的所有邊的容量都改為 $\infty$。
然後你就會發現一個特別噁心的事情,對於每一問都得重新建圖。
(十四)P2764 最小路徑覆蓋問題
題意:給定一個 $\texttt{DAG}$,最少多少條簡單路徑能覆蓋所有點。輸出路徑。
關於這道題有一個非常巧妙的解法。
首先發現答案的上限是 $n$,因為每一個點都可以被它直連的一條邊覆蓋,一共 $n$ 個點,所以答案最多是 $n$。
然後考慮合併邊,每合併兩條邊答案就減少 $1$,所以考慮通過最大流來找出邊的最大合併數。
這樣就很好做了,對於每一個點拆點,然後 $s$ 連向每一個入點,容量 $1$,每一個出點連向 $t$,容量 $1$,之後對於每一條 $(x,y)$,連 $x$ 到 $y'$ 的一條容量為 $1$ 的邊即可。表示合併了兩個點。
最後跑一邊最大流,答案就是 $n$ 減去最大流。
輸出方案採用並查集維護起點,然後對於每一個起點順著殘餘網路暴力 $dfs$ 即可。
(十五)P4009 汽車加油行駛問題
題意:給定 $n\times n$ 的方格,坐上 $(1,1)$ 為起點,右下 $(N,N)$ 為終點,$X$ 軸向右為正,$Y$ 軸向下為正,在若干個點上設定了油庫可供加油,汽車只能沿著網格邊走,遇到加油站必須加油,裝滿油後最多走 $k$ 條邊,初始油量已滿。汽車移動時若 $X$ 或 $Y$ 座標減小,則需花費 $B$ 的費用。加油需要花 $A$ 的費用,可以在某一個沒有加油站的點花 $C$ 的費用使油量變滿。求最小費用。
這道題很顯然是分層圖最短路,所以考慮網路瘤。
顯然費用流。
我們將圖分為 $k+1$ 層,第 $0$ 層表示滿油,第 $i$ 層表示用掉了 $i$ 個單位的油。第 $k$ 層就表示油被用光。
我們用三元組 $(x,y,z)$ 表示一個點 $(x,y)$ 的已用油量 $z$。
建立虛擬源點 $s$ 和虛擬匯點 $t$。
首先從 $s$ 到 $(1,1,0)$ 連一條流量 $1$,費用為 $0$ 的邊,表示初始油量已滿。對於每一個 $i$ 連從 $(n,n,i)$ 到 $t$ 的流量為 $1$,費用為 $0$ 的邊,表示到達終點後車的可能的 $k+1$ 種狀態。
之後考慮有加油站的點 $(i,j)$,汽車會被強制消費。所以 $(i,j,z)$ 連向 $(i,j,z+1)$ 流量 $1$,費用 $A$ 的邊。然後列舉周圍點,從狀態 $0$ 到狀態 $1$ 連邊。注意如果橫縱座標減小應該額外花費 $b$。
然後對於普通點也是同理,只不過連周圍點的時候要列舉當前點的狀態。
特殊的,若當前點的狀態是 $k$ 即油沒了,連一條 $(i,j,k)$ 向 $(i,j,0)$ 流量 $1$ 費用 $a+c$ 的邊。
(十六)深海機器人問題
題意:有一個 $P\times Q$ 的網格圖,左下角為 $(0,0)$,右上角為 $(Q,P)$。有 $k$ 個機器人在不同出發地點,有若干目標地點,每個目標地點只能容納 $r_i$ 個機器人,有些地方有生物標本,每個生物標本有價值,每個生物標本只能被第一個到達它的機器人取走,機器人只能向北或東走,若干機器人可以佔據同一位置。求最高價值。
很顯然的最大費用最大流了。每個點分別向右邊的點連兩條邊,一條容量 $1$,費用為該點價值,一條容量無限,費用 $0$,表示取走一次再不能取。向上同理。
最後把起點和 $s$ 連起來,終點和 $t$ 連起來,容量為機器人數目,費用為 $0$。
最後跑最大費用最大流即可。
(十七)最長 $k$ 重線段集問題
題意:給定平面直角座標系 $n$ 個線段,從這些區間中選取一些線段,使得對於任意一點 $p$ 沒有任何一條直線 $x=p$ 與超過 $k$ 個線段,並使得線段長度最大值。
其實是最長 $k$ 重區間集問題的升級版,把區間放到直角座標系上了。
那麼一個很直接的想法就產生了,直接把線段投影到 $x$ 軸上!這樣就和最長 $k$ 重區間集問題一模一樣了。
但是很遺憾,這個想法是錯誤的,反例也很簡單,假設說兩條線段在一條是平行於 $y$ 軸的,投影之後就變成一個點了,導致錯誤。
那麼不難想到把線段的長度都擴大一倍,即將線段 $i$ 的左右端點 $x_i,y_i$ 都擴大一倍變成 $(2x_i,2y_i)$。
而對於一個左右端點相同的區間,可以將它更改成 $(2x_i,2x_i+1)$。其它節點也都需要更改成 $(2x_i+1,2y_i)$ 的形式。
(十八)魔術球問題
題意:$n$ 個柱子,依次放入無限個球,球從 $1$ 開始編號。每次只能在某根柱子最上面放球,並且在同一個柱子中,任何兩個相鄰球的編號之和為完全平方數。輸出方案。
我們考慮當前放置的球 $i$,它有兩種可能,一是放到某一根已經有魔術球的柱子上,二是自己放到一個新的桌子上。
我們將球分裂,一個入點,一個出點。
首先我們可以將 $s$ 連向入點,容量為 $1$,表示放到一個新的柱子上。出點連向 $t$,容量也為 $1$,這裡很重要,表示我們成功放上了一個球。
然後列舉可以與它構成完全平方數的數 $x$,將 $x$ 的入點連向它的出點,容量為 $1$,表示一個匹配關係。
跑最大流,直到最大流大於 $n$,說明所需的柱子量超過了 $n$,那麼停止。
輸出方案找流量為 $0$ 的邊,暴力 $\texttt{dfs}$ 即可。
還有億點細節。
(十九)火星探險問題
題意:給定一張網格圖,每個點有三種狀態,平坦,障礙或岩石標本。有 $n$ 個探測車在移動中須採集岩石標本。每一塊岩石標本由最先遇到它的探測車完成採集。每塊岩石標本只能被採集一次。岩石標本被採集後,其他探測車可以從原來岩石標本所在處通過。探測車不能通過有障礙的地面。探測車只能從登陸處沿著向南或向東的方向朝傳送器移動,而且多個探測車可以在同一時間佔據同一位置。如果某個探測車在到達傳送器以前不能繼續前進,則該車所採集的岩石標本將全部損失。求最多獲得的岩石標本數。要求列印移動方向。
一道非常板的網路流了。顯然車的數量為流量,石頭數為費用。
令 $s$ 向 $(1,1)$ 連流量 $n$ 費用 $0$ 的邊,表示初始有 $n$ 輛車。$(n,n)$ 連向 $t$,容量 $\infty$,花費 $0$,表示結束任務。
既然涉及到每個石頭只能取一次,那麼顯然是可以拆點的,拆為 $a_{i,j}$ 和 $b_{i,j}$。
如果 $(i,j)$ 處有石頭,那麼可以連 $(a_{i,j})$ 到 $b_{i,j}$ 的流量 $1$,費用 $1$ 的邊,表示只能有一個車取一個石頭。石頭也可以被取走,連另連一條流量 $\infty$ 費用 $0$ 的邊。
另外還有相鄰的點連線,每次都是出點連入點,流量 $\infty$ 然後費用 $0$。
最後就是最大費用最大流。
輸出路徑還是暴力 $\text{dfs}$。
$$\texttt{The End.by UF}$$