«問題描述:
給定有向圖g=(v,e)。設p 是g 的乙個簡單路(頂點不相交)的集合。如果v 中每個頂點恰好在p 的一條路上,則稱p是g 的乙個路徑覆蓋。p 中路徑可以從v 的任何乙個頂點開始,長度也是任意的,特別地,可以為0。g 的最小路徑覆蓋是g 的所含路徑條數最少的路徑覆蓋。設計乙個有效演算法求乙個有向無環圖g 的最小路徑覆蓋。
每條邊的容量均為1。求網路g1的( 0 x , 0 y )最大流。
«程式設計任務:
對於給定的給定有向無環圖g,程式設計找出g的乙個最小路徑覆蓋。
輸入格式:
件第1 行有2個正整數n和m。n是給定有向無環圖g 的頂點數,m是g 的邊數。接下來的m行,每行有2 個正整數i和j,表示一條有向邊(i,j)。
輸出格式:
從第1 行開始,每行輸出一條路徑。檔案的最後一行是最少路徑數。
輸入樣例#1:
11 12輸出樣例#1:1 21 3
1 42 5
3 64 7
5 86 9
7 10
8 11
9 11
10 11
1 4 7 10 111<=n<=150,1<=m<=60002 5 8
3 6 9
3
可能很多人看到這個提示反而更懵逼了。先解釋一下題意,大概就是給你有向圖,樣例是一張這樣的圖:
然後求出的最小路徑數就是3了,三條路徑也很容易可以看出。
我們先考慮一下如何求出二分圖的最小路徑覆蓋。
這裡介紹乙個定理:
最小路徑覆蓋數=|g|-二分圖最大匹配數(|g|是有向圖中的總邊數)
為什麼是這樣的呢?首先我們知道,在二分圖中乙個點就代表者一條路徑。那麼如果此時二分圖內沒有連邊,這個公式是成立的。每當二分圖內增加一條邊,最大匹配數就會+1,而一條匹配邊會連線二分圖中的兩個點,那麼兩個點間本來有兩條路徑覆蓋,就變成了一條。同理,每加入一條邊匹配數就會+1,路徑覆蓋數就會-1。所以這個公式是成立的。但是這個公式是對二分圖適用的,如何將它轉化到這個問題上來呢?
這時我們先將乙個點拆a成出點ax和入點ay,那麼在連有向邊a -> b的時候就將ax連向by。就將有向圖變成了乙個二分圖。我們看一下樣例轉化為二分圖的樣子(n == 11)。
那麼這樣我們只需要求出將每個點拆點組成二分圖後的最大匹配就可以了。
最後在輸出路徑的時候就記錄下每個入點的連入邊,然後用並查集記錄一下一條路徑的起點就好了。
1 #include2using
namespace
std;
3const
int n=15000+5;4
const
int inf=2147483647;5
6int
n, m, s, t;
7int cnt = 1;8
int ans = 0;9
int last[n*10
];10
int lev[n*10
];11
int fa[n*10
];12
13struct
edgee[n*10
];16
17void add(int x,int y,int
z)24
25bool
bfs()35}
36return lev[t] != -1;37
}3839int dfs(int x,int
flow)51}
52}53return
rest;54}
5556
int find(int
x)60
61void output(int
x)67
68int
main()
75for(int i=1;i<=n;i++) add(s,i,1),add(i,s,0
);76
for(int i=n+1;i<=n*2;i++) add(i,t,1),add(t,i,0
);77
while(bfs()) ans +=dfs(s,inf);
78for(int i=1;i<=n;i++) fa[i] =i;
79for(int i=2;i<=cnt;i++)
84for(int i=1;i<=n;i++)
85if(fa[i] == i) output(i), cout <
86 cout << n-ans <
87return0;
88 }
網路流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題 最小路徑覆蓋問題
p2764 傳送門 基本模型 首先結論為 將每個點 v 拆成 v,v 有向邊 edge u,v 改為 edge u,v 建成二分圖 那麼 最小路徑覆蓋數 n 二分圖最大匹配數 證明 匹配 u,v 相當於連線了 u,v 連通塊個數減一,想要連通塊最少自然要最大匹配 如果要輸出方案的話增廣時記錄 u 的...