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...