網路流24題 最小路徑覆蓋問題

2022-05-31 04:06:13 字數 2457 閱讀 1972

傳送門:>here

<

題意:求dag的最小路徑覆蓋並輸出方案。所謂最小路徑覆蓋是指,將原圖分為若干條路徑,任意兩條路徑不能有公共點,要使路徑數量盡可能少

思路分析

依然能夠聯絡到二分圖。事實上這個問題在學二分圖的時候提到過,然而當時並沒有弄明白……

公式:dag的最小路徑覆蓋 = 頂點數 - 最大匹配

千萬不要弄混淆的是這裡的最大匹配並不是指直接在dag上做最大匹配,而是需要拆點然後搞。

具體過程如下:

原圖共有n個點。將每個點$i$拆成兩個點,記為$x_i$與$y_i$,對於任意一條原圖中的邊$(u,v)$,連線$(x_u, y_v)$(有向邊)。很容易發現,左半部對應著每條邊的起點,右半部對應著終點。然後以x為左半部,y為右半部做二分圖的最大匹配,得到答案ans,則最小路徑覆蓋就是n-ans。

為什麼最小路徑覆蓋就是n-ans呢?

假設拆點建的圖中一條匹配邊都沒有——也就意味著沒有邊。此時每乙個頂點為一條路徑,最小路徑覆蓋為n。

然後,在拆點建的圖中增加一條匹配邊,我們發現這對應著原圖中的乙個點融入了另一條路徑,因此最小路徑覆蓋要-1。進一步我們發現,每增加一條能夠匹配的邊,就意味著原圖中的又乙個點加入到了某一條路徑當中。因此最小路徑覆蓋會-1。因此有多少條匹配邊就減幾次。所以要讓答案最小,也就是讓匹配邊盡量多。問題轉化為了二分圖的最大匹配問題

那為什麼我們要拆點呢?原因在於原圖是乙個有向圖,對於乙個路徑內部的點(非起點、終點),一定有一條邊進入它,一條邊從它出。如果直接拿原圖做二分圖匹配不會容許乙個點有兩條邊的情況。而拆點以後,左側的點僅僅作為起點,右側的點僅僅作為終點,因此這種情況對應到每乙個點依然只有一條邊。如果乙個點出發有兩條邊,對應著原圖中乙個點作為起點有兩條邊,此時由於要求最小路徑覆蓋,必須捨棄一條邊,二分圖匹配會自動捨棄另一條邊。所以二分圖內的所有匹配都不會發生這種矛盾的情況,也就意味著每有一條匹配邊,就可以多將乙個點歸入一條路徑

以上是公式的原理,下面來談如何輸出方案。

對於每乙個起點,我們記錄它出發是否有一條飽和弧到達乙個終點,如果有,意味著它一定不是終點。我們對於每乙個點記錄乙個由它出發到達的點(sec),以及以它作為終點的邊的那個起點(pre)。如果當前點不作為任何一條邊的終點,那它就是起點;反之,如果不到達任何乙個其他點,那麼它就是終點。因此我們只需要列舉每個點以及由他延伸出去的弧,檢視每條弧是否飽和,若飽和則說明這是匹配邊,記錄sec和pre即可

code

/*

by dennyqi

*/#include

#include

#include

#include

#define r read()

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

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

using

namespace

std;

typedef

long

long

ll;const

int maxn = 10010

;const

int maxm = 10010

;const

int inf = 1061109567

;inline

intread()

intn,m,s,t,x,y,ans_min;

int first[maxm*2],nxt[maxm*2],to[maxm*2],cap[maxm*2],flow[maxm*2],num_edge=-1

;int

level[maxn],cur[maxn],pre[maxn],sec[maxn];

queue

q;inline

void add(int u, int v, int c, int

f)inline

bool

bfs()}}

return level[t]!=0;}

int dfs(int u, int

a) }

return

ans;

}inline

void

dinic()

ans_min = n -ans;

}int

main()

for(int i = 1; i <= n; ++i)

dinic();

for(int i = 1; i <= n; ++i)}}

for(int i = 1; i <= n; ++i)

printf(

"%d\n

",u);}}

printf("%d

", ans_min);

return0;

}

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

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

網路流24題 最小路徑覆蓋問題

有向無環圖最小路徑覆蓋,可以轉化成二分圖最大匹配問題,從而用最大流解決。構造二分圖,把原圖每個頂點i拆分成二分圖x,y集合中的兩個頂點xi和yi。對於原圖中存在的每條邊 i,j 在二分圖中連線邊 xi,yj 然後把二分圖最大匹配模型轉化為網路流模型,求網路最大流。最小路徑覆蓋的條數,就是原圖頂點數,...

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

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