luogu P2764 最小路徑覆蓋問題

2022-05-30 21:36:11 字數 1489 閱讀 2837

給定有向圖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 行開始,每行輸出一條路徑。檔案的最後一行是最少路徑數。

輸入樣例#1:

11 12

1 21 3

1 42 5

3 64 7

5 86 9

7 10

8 11

9 11

10 11

輸出樣例#1:

1 4 7 10 11

2 5 8

3 6 9

3

先假設每個點是一條路徑,那麼現在有n條路徑。

然後考慮一些路徑的合併,顯然合併盡可能多的路徑可以最小化路徑條數。

然後考慮網路流建模,對於每個點拆成兩個,連二分圖

對於邊,連<\(u_x,v_y\)>,容量為1 。

對於\(x\)的點,連<\(s,x\)>,對於\(y\),連<\(y,t\)>,容量都為1,這樣可以保證每乙個點只連一條邊出去,只有一條邊連向它。

這樣,每條增廣路都只經過兩個點,可以看成合併兩條鏈。

然後求最大流,答案就是\(n-max\_flow\).

#pragma gcc optimize(3)

#includeusing namespace std;

void read(int &x)

void print(int x)

void write(int x)

#define maxn 5050

const int inf=2e9;

int n,m,s,t,head[maxn],tot=1,dis[2004],vis[2004],max_flow;

struct edgee[maxn<<1];

void add(int u,int v,int w) ,head[u]=tot;}

void ins(int u,int v,int w)

int bfs()

}return dis[t]<1e9;

}int dfs(int x,int f)

return used;

}void dinic()

}int nxt[maxn],pre[maxn];

int main()

write(n-max_flow);

return 0;

}

Luogu P2764 最小路徑覆蓋問題

洛谷傳送門 給定有向圖g v,e g v,e 設p p 是g role presentation style position relative g g的乙個簡單路 頂點不相交 的集合。如果 v v 中每個頂點恰好在 p role presentation style position relati...

P2764 最小路徑覆蓋

我們首先將原圖用n條路徑覆蓋,每條邊只經過乙個節點 本身 可以知道每合併兩條路徑,路徑覆蓋數就會減少1。現在盡量合併更多的路徑 即將兩個路徑通過一條邊首尾相連 所以拆點做二分圖最大匹配即可。includeusing namespace std const int maxn 510 const int...

P2764 最小路徑覆蓋問題

我做24題的第六題,輸出路徑還是有點糊塗 給定有向圖g v,e 設p是圖g上若干點不相交的簡單路徑的集合,若每個點v屬於v都存在於唯一一條p中的路徑上,則p是g的一條路徑覆蓋。路徑數量最少的路徑覆蓋稱為最小路徑覆蓋。用minpc g 表示圖g的最小路徑覆蓋數.有向無環圖的最小路徑覆蓋問題可轉化為二分...