傳送門:>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 的所含路徑條數最少的路徑覆蓋。設計乙個有效演算法求乙個有...