我做24題的第六題,輸出路徑還是有點糊塗
給定有向圖g=(v,e),設p是圖g上若干點不相交的簡單路徑的集合,若每個點v屬於v都存在於唯一一條p中的路徑上,則p是g的一條路徑覆蓋。路徑數量最少的路徑覆蓋稱為最小路徑覆蓋。用minpc(g)表示圖g的最小路徑覆蓋數.有向無環圖的最小路徑覆蓋問題可轉化為二分圖的最大匹配問題。給定有向無環圖g=(v,e),設v=,將點i屬於v拆成xi、yi兩個點,若(i,j)屬於e,則連一條無向邊(xi,yi)。得到二分圖g』.
最小路徑覆蓋=頂點數-最大匹配
考慮從g0=(v,空集)開始,往圖中新增邊的過程。初始時,每個點v屬於v自成一條路徑,有minpc(g0)=n.希望每次加入的那條邊能將兩條簡單的路徑合為一條,所以這條邊應起始於某條路徑的終點,終止於另一條路徑的起點,反覆如此新增,直至無法操作為止。將新增過程中得到的圖依次記為g1,g2…,問題就歸結為最多能加入多少條這樣的邊。不難發現,g『上的匹配m和上述方案是一一對應的:l中的某個未匹配點表示某條路徑的終點,r中的某個未匹配點表示某條路徑的起點,所以minpc(gi)=n-i,於是minpc(g)=n-|m』|.
然後我寫一下自己想的,有可能會有偏差。路徑覆蓋就是每一條路徑都覆蓋不重複的點。最小路徑覆蓋數就是問用最少的路徑數量可以覆蓋所有的頂點。一開始每乙個頂點算乙個路徑,也就是minpc(g0)=n,依次將可以連線的兩個點連線起來,使一條路徑盡可能多的覆蓋點.乙個二分圖g,在g的乙個子圖m中, m的邊集中的任意兩條邊都不交匯於同乙個結點,則稱m是乙個匹配。所以說尋找最小覆蓋路徑問題可以轉化為二分圖的最大匹配。
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using
namespace std;
const
int n=
6e4+5;
const
int maxn=
1e3;
struct node
s[n]
;int pre[maxn+10]
;int tag[maxn+10]
;int cnt,head[n]
,dis[n]
;int a,t;
int n,m;
void
add(
int u,
int v,
int cap)
bool
bfs()}
}return dis[t]!=0
;}intdfs
(int u,
int flow)
for(
int e=head[u]
;~e;e=s[e]
.to)
} dis[u]=-
1;return0;
}int
dinic()
}for
(int i=
1;i<=n;i++)}
if(ok)
cout<}return ans;
}void
init()
///3?ê??ˉ
intmain()
for(
int i=
1;i<=n;i++
)int num=
dinic()
;printf
("%d\n"
,n-num)
;return0;
}
P2764 最小路徑覆蓋問題
問題描述 每條邊的容量均為1。求網路g1的 0 x 0 y 最大流。程式設計任務 對於給定的給定有向無環圖g,程式設計找出g的乙個最小路徑覆蓋。輸入格式 件第1 行有2個正整數n和m。n是給定有向無環圖g 的頂點數,m是g 的邊數。接下來的m行,每行有2 個正整數i和j,表示一條有向邊 i,j 輸出...
P2764 最小路徑覆蓋問題
給定有向圖 g v,e g v,e 設 p 是 g 的乙個簡單路 頂點不相交 的集合。如果 v 中每個定點恰好在p的一條路上,則稱 p 是 g 的乙個路徑覆蓋。p中路徑可以從 v 的任何乙個定點開始,長度也是任意的,特別地,可以為 0 g 的最小路徑覆蓋是 g 所含路徑條數最少的路徑覆蓋。設計乙個有...
P2764 最小路徑覆蓋問題
每條邊的容量均為1。求網路g1的 0 x 0 y 最大流。對於給定的給定有向無環圖g,程式設計找出g的乙個最小路徑覆蓋。檔案第1 行有2個正整數n和m。n是給定有向無環圖g 的頂點數,m是g 的邊數。接下來的m行,每行有2 個正整數i和j,表示一條有向邊 i,j 從第1 行開始,每行輸出一條路徑。檔...