Luogu P2764 最小路徑覆蓋問題

2021-08-22 10:19:19 字數 2919 閱讀 8151

洛谷傳送門

給定有向圖g=

(v,e

) g=(

v,e)

。設p p

是g' role="presentation" style="position: relative;">g

g的乙個簡單路(頂點不相交)的集合。如果

v v

中每個頂點恰好在

p' role="presentation" style="position: relative;">p

p的一條路上,則稱

p p

是g' role="presentation" style="position: relative;">g

g的乙個路徑覆蓋。

p p

中路徑可以從

v' role="presentation" style="position: relative;">v

v的任何乙個頂點開始,長度也是任意的,特別地,可以為

0 0

。g' role="presentation" style="position: relative;">g

g的最小路徑覆蓋是

g g

的所含路徑條數最少的路徑覆蓋。設計乙個有效演算法求乙個有向無環圖

g' role="presentation" style="position: relative;">g

g的最小路徑覆蓋。

輸入格式:第1

1

行有2' role="presentation" style="position: relative;">2

2個正整數

n n

和m' role="presentation" style="position: relative;">mm。

n n

是給定有向無環圖

g' role="presentation" style="position: relative;">g

g的頂點數,

m m

是g' role="presentation" style="position: relative;">g

g的邊數。接下來的

m m

行,每行有

2' role="presentation" style="position: relative;">2

2個正整數i和

j j

,表示一條有向邊(i

,j)' role="presentation" style="position: relative;">(i,

j)(i

,j)。

輸出格式:從第1

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

1≤

n≤150,1≤

m≤6000

' role="presentation" style="position: relative;">1≤n

≤150,1

≤m≤60001≤

n≤150,1≤

m≤6000

我們把兩個點合在一起的時候, 總的路徑條數便減1。因此我們實際上是在求相鄰點與點之間的最優匹配, 直接換為二分圖模型。對於所有的e(

a,b)

e (a

,b

), 我們連xa

→yb xa→

yb

這樣一條容量為1的邊。 最終最小路徑數便為點數減去最優匹配數。

至於輸出方案, 直接使用並查集維護所在鏈端即可。

**如下:

#include 

#include

#include

#include

#include

#include

#include

#define r register

#define in inline

#define gc getchar()

#define w while

#define s 0

#define t 500

#define mx 505

#define inf 100000000

template

in void in(tt &x)

int dot, line, cnt = -1;

int head[mx], layer[mx], bel[mx];

struct edge edge[mx * 100];

std::queue

q;in void add(r int from, r int to, r int fl)

, head[from] = cnt;

edge[++cnt] = , head[to] = cnt;

}int find(r int now)

in bool bfs()

}return layer[t];

}int dfs(r int now, r int val)

}return val - lef;

}int dinic()

void print(r int now)

int main(void)

}for (r int i = 1; i <= dot; ++i) if(bel[i] == i) print(i), putchar(10);

printf("%d", ans);

}

luogu P2764 最小路徑覆蓋問題

給定有向圖g v,e 設p 是g 的乙個簡單路 頂點不相交 的集合。如果v 中每個頂點恰好在p 的一條路上,則稱p是g 的乙個路徑覆蓋。p 中路徑可以從v 的任何乙個頂點開始,長度也是任意的,特別地,可以為0。g 的最小路徑覆蓋是g 的所含路徑條數最少的路徑覆蓋。設計乙個有效演算法求乙個有向無環圖g...

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的最小路徑覆蓋數.有向無環圖的最小路徑覆蓋問題可轉化為二分...