題目:
給定有向圖g=(v,e)。設p是g的乙個簡單路(頂點不相交)的集合。如果v中每個頂點恰好在p的一條路上,則稱p是g的乙個路徑覆蓋。p中路徑可以從v的任何乙個頂點開始,長度也是任意的,特別地,可以為0。g的最小路徑覆蓋是g的所含路徑條數最少的路徑覆蓋。
設計乙個有效演算法求乙個有向無環圖g的最小路徑覆蓋。
輸入格式:
第1行有2個正整數n和m。n是給定有向無環圖g的頂點數,m是g的邊數。
接下來的m行,每行有2個正整數i 和j,表示一條有向邊(i,j)。
輸出格式:
從第一行開始,每行輸出1條路徑,檔案的最後一行是最小路徑數。
思路:我們將每個點拆成i和
i+n,因為頂點不相交,那麼這個圖就成了乙個二分圖
最小路徑覆蓋=頂點數-二分圖最大匹配
證明:我們先把每個頂點看成一條單獨的路徑,花費記為1,假設一開始有11個點,那麼總花費是11,此時如果有一條邊連線了1和2,即1和2匹配,那麼總花費變成10
所以要想用最小的路徑覆蓋所有頂點,那麼要求出這個二分圖中的最大匹配,用頂點總數減去二分圖最大匹配即為答案。跑一遍最大流來求二分圖的最大匹配。
然後輸出路徑的方法是:如果這條邊上的流量為0,那麼說明經過了這條路徑,再以這個點為起點繼續尋找,跑一遍dfs即可
**:
#include #include#include
#include
#include
using
namespace
std;
const
int maxn=2e5+5
;const
int inf=0x7fffffff
;typedef
long
long
ll;int
head[maxn],tot,visit[maxn];
ints,t,n,m;
struct
node
e[maxn];
void add(int x,int y,int
z)void add_edge(int x,int y,int
z)int
deep[maxn],l,r,q[maxn];
bool
bfs()}}
return
deep[t];
}int dfs(int u,int
min_f)}}
if(!temp_f)deep[u]=-1
;
return
temp_f;
}int
dinic()
vector
path;
void print(intu)}
intmain()
int ans=dinic();
for(int i=1;i<=n;i++)
}printf(
"%d\n
",n-ans);
return0;
}
網路流24題 最小路徑覆蓋問題
有向無環圖最小路徑覆蓋,可以轉化成二分圖最大匹配問題,從而用最大流解決。構造二分圖,把原圖每個頂點i拆分成二分圖x,y集合中的兩個頂點xi和yi。對於原圖中存在的每條邊 i,j 在二分圖中連線邊 xi,yj 然後把二分圖最大匹配模型轉化為網路流模型,求網路最大流。最小路徑覆蓋的條數,就是原圖頂點數,...
最小路徑覆蓋 網路流24題 3 24
最小路徑覆蓋 題面 給定有向圖g 設 p是 g的乙個簡單路 頂點不相交 的集合。如果 v中每個頂點恰好在 p的一條路上,則稱 p是 g的乙個路徑覆蓋。p中路徑可以從 v的任何乙個頂點開始,長度也是任意的,特別地,可以為0 g的最小路徑覆蓋是 g 的所含路徑條數最少的路徑覆蓋。設計乙個有效演算法求乙個...
最小路徑覆蓋問題(網路流24題)
問題描述 給定有向圖g v,e 設p 是g 的乙個簡單路 頂點不相交 的集合。如果v 中每個頂點恰好在p 的一條路上,則稱p是g 的乙個路徑覆蓋。p 中路徑可以從v 的任何乙個頂點開始,長度也是任意的,特別地,可以為0。g 的最小路徑覆蓋是g 的所含路徑條數最少的路徑覆蓋。設計乙個有效演算法求乙個有...