思路:
每個點x拆成兩個點x和x',分別表示x作為前驅和作為後繼。若原圖中x和y有邊,向x和y'加一條有向邊。如此構成二分圖,記此二分圖中作為前驅的節點集合為a,作為後繼的節點集合為b。跑最大匹配,沒有匹配的點的個數(n-最大匹配數)就是需要的最少的路徑條數。正確性:二分匹配可以保證每個點頂多只有乙個前驅,並且頂多只有乙個後繼,也就保證了每個點在且僅在一條路徑中。此外,在二分圖中,a中每個沒有匹配的頂點對應了一條路徑的終點。(類似地,b中每乙個沒有匹配的頂點對應了一條路徑的起點。)最大二分匹配可以保證a(或b)中沒有匹配的點的數量最少,亦即路徑條數最少。
實現:
1 #include 23#define n (1000 + 2)
4#define m (n * n + 4 * n)
56 typedef long
long
ll;7
8using
namespace
std;910
struct
edge 11;
14edge e[m];
1516
inthead[n], level[n], cur[n];
17int
num_of_edges;
1819
/*20
* when there are multiple test sets, you need to re-initialize before each
21*/
22void dinic_init(void
) 23
2829
int add_edge(int u, int v, int c1, int
c2)
3045
46void print_graph(int
n) 47
55 printf("\n"
);56}57
return;58
}5960/*
61* find all augmentation paths in the current level graph
62* this is the recursive version
63*/
64int dfs(int u, int t, int
bn)
6583}84
}85if (left > 0) level[u] = 0;86
return bn -left;87}
8889
bool bfs(int s, int
t) 90
108}
109}
110return
false
;111
}112
113 ll dinic(int s, int
t) 114
122return
max_flow;
123}
124125
intmain()
126135
for (int i = 1; i <= n; i++)
136140
int ans = dinic(0, 2 * n + 1
);141 cout << n - ans <142return0;
143 }
網路流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...
網路流四 最小路徑覆蓋
h市一共有n個旅遊景點 編號1.n 由m條單向遊覽路線連線。在乙個景點遊覽完後,可以順著遊覽線路前往下乙個景點。為了避免遊客重複遊覽同乙個景點,遊覽線路保證是沒有環路的。每乙個調查團可以從任意乙個景點出發,沿著計畫好的遊覽線路依次調查,到達終點後再返回。每個景點只會有乙個調查團經過,不會重複調查。舉...