網路流四 最小路徑覆蓋

2021-07-23 10:25:36 字數 2275 閱讀 4120

h市一共有n個旅遊景點(編號1..n),由m條單向遊覽路線連線。在乙個景點遊覽完後,可以順著遊覽線路前往下乙個景點。

為了避免遊客重複遊覽同乙個景點,遊覽線路保證是沒有環路的。

每乙個調查團可以從任意乙個景點出發,沿著計畫好的遊覽線路依次調查,到達終點後再返回。每個景點只會有乙個調查團經過,不會重複調查。

舉個例子:

上圖中一共派出了3個調查團:

1. 藍色:調查景點;2

2. 橙色:調查景點;1->3->4->6

3. 綠色:調查景點;5->7

當然對於這個圖還有其他的規劃方式,但是最少也需要3個調查團。

由於小組內的人數有限,所以大家希望調查團的數量盡可能少,同時也要將所有的景點都進行調查。

輸入第1行:2個整數n,m。1≤n≤500,0≤m≤20,000。

第2..m+1行:2個數字u,v,表示一條有向邊(u,v)。保證不會出現重複的邊,且不存在環。

輸出第1行:1個整數,表示最少需要的調查團數量。

樣例輸入

7 7

1 21 3

2 43 4

4 54 6

5 7

樣例輸出

對於一條路徑,起點的入度為0,終點的出度為0,中間節點的出入度都為1。

每乙個點最多只能有1個後繼,同時每乙個點最多只能有1個前驅。

假如我們選擇了一條邊(u,v),也就等價於把前驅u和後繼v匹配上了。這樣前驅u和後繼v就不能和其他節點匹配。

利用這個我們可以這樣來構圖:

將每乙個點拆分成2個,分別表示它作為前驅節點和後繼節點。將所有的前驅節點作為a部,所有後繼節點作為b部。

接下來進行連邊,若原圖中存在一條邊(u,v),則連線a部的u和b部的v。

在這個上面做乙個最大二分匹配:

其中實線表示被選中的匹配,虛線表示未被選中的。

有沒有發現,和原圖剛好有著對應的關係。

這樣在匹配結束的時候,我們就可以直接通過匹配的情況來確定選中的路徑。

但是如何保證這樣就能得到最小的路徑覆蓋呢?

如果乙個點是路徑起點的話,它在b部的節點一定是沒有匹配上的。

經過最大匹配演算法後,b部剩下沒有被匹配的點一定是最少的,也就對應了最小需要的路徑數。

所以最小路徑覆蓋的結果才是n-最大匹配數。

正是這樣,這樣問題也就解決了。接下來第二個問題,怎麼用網路流來解決二分匹配呢?

上一次我們講了二分多重匹配,二分匹配不就是它的簡化版麼。

只需要把源點s到a部的邊和b部到匯點t的邊容量限定為1就可以了!

#include #include #include #include #include #define max 1010

#define maxcf 101

#define min(a,b) (a)>(b)?(b):(a)

using namespace std;

int cf[max][max];//儲存圖

int queue[max];//搜尋佇列

int path[max];//儲存路徑

int capacity[max];//流量陣列,儲存經過該點的最小流量

bool visited[max];//記錄訪問陣列

int findaugmentpath(int t)

} i++;

} return 0;

}void modifygraph(int t)

}int main()

for (i = 0; i < m; ++i)

int maxflow = 0;

int delta = 0;

while (delta = findaugmentpath(e))

cout << n - maxflow << endl;

}return 0;

}

網路流最小路徑覆蓋

思路 每個點x拆成兩個點x和x 分別表示x作為前驅和作為後繼。若原圖中x和y有邊,向x和y 加一條有向邊。如此構成二分圖,記此二分圖中作為前驅的節點集合為a,作為後繼的節點集合為b。跑最大匹配,沒有匹配的點的個數 n 最大匹配數 就是需要的最少的路徑條數。正確性 二分匹配可以保證每個點頂多只有乙個前...

網路流24題 最小路徑覆蓋 (最小路徑覆蓋)

題目 給定有向圖g v,e 設p是g的乙個簡單路 頂點不相交 的集合。如果v中每個頂點恰好在p的一條路上,則稱p是g的乙個路徑覆蓋。p中路徑可以從v的任何乙個頂點開始,長度也是任意的,特別地,可以為0。g的最小路徑覆蓋是g的所含路徑條數最少的路徑覆蓋。設計乙個有效演算法求乙個有向無環圖g的最小路徑覆...

網路流 最小路徑覆蓋問題

每條邊的容量均為1。求網路g1的 x0,y0 最大流。對於給定的給定有向無環圖g,程式設計找出g的乙個最小路徑覆蓋。輸入 由檔案input.txt提供輸入資料。檔案第1 行有2個正整數n和m。n是給定有向無環圖 g 的頂點數,m是g 的邊數。接下來的m行,每行有2 個正整數i和j,表示一條有向邊 i...