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