題解 最小路徑覆蓋問題 網路流

2022-02-23 20:38:06 字數 1362 閱讀 3975

考慮最終的那些覆蓋路徑的樣子是什麼,顯然是很多點和很多鏈(廢話),但是學過生物必修一肽鏈和蛋白質的人都能發現,路徑條數=\(n-m'\),\(n\)是點的個數,\(m'\)是選出來的邊的條數。

這裡的\(n\)是個定值,問題轉變了選出最多的邊\(m'\),使得選出的邊不存在共同的起點或終點。

也就是說,乙個點可以同時作為起點和終點,但是不能被兩條邊同時連線。考慮邊是有起點的,也就是說,乙個終點可以且僅可以和乙個起點匹配,每成功匹配到乙個就說明可以選出一條邊

起點終點匹配=二分圖匹配=最大流=\(m'\)

總結起來,可以得到乙個方法:選邊=匹配起點和終點

//@winlere

#include#include#include#include#includeusing namespace std; typedef long long ll;

inline int qr()

int cnt=1;

const int inf=0x3f3f3f3f;

int s,t,m,n;

struct e

e(const int&a,const int&b,const int&c)

}e[48005];

int head[355];

inline void add(const int&fr,const int&to,const int&w,const int&f=1)

const int maxn=355;

int sum=0;

queue < int > q;

int d[maxn],cur[maxn];

inline bool bfs()}}

return d[t];

}int dfs(const int&now,int fl)

}return ret;

}inline int dinic()

namespace getans

int n;

inline void main(const int&a)

if(!dr[t])

}for(auto t:ve)

}}int main()

int ans=n-dinic();

for(register int t=1;t<=n;++t)

for(register int i=head[t];i;i=e[i].nx)

if(e[i].w==0&&e[i].to>=n&&e[i].to<=n+n)

getans::main(n);

printf("%d\n",ans);

return 0;

}

網路流 最小路徑覆蓋問題

每條邊的容量均為1。求網路g1的 x0,y0 最大流。對於給定的給定有向無環圖g,程式設計找出g的乙個最小路徑覆蓋。輸入 由檔案input.txt提供輸入資料。檔案第1 行有2個正整數n和m。n是給定有向無環圖 g 的頂點數,m是g 的邊數。接下來的m行,每行有2 個正整數i和j,表示一條有向邊 i...

網路流最小路徑覆蓋

思路 每個點x拆成兩個點x和x 分別表示x作為前驅和作為後繼。若原圖中x和y有邊,向x和y 加一條有向邊。如此構成二分圖,記此二分圖中作為前驅的節點集合為a,作為後繼的節點集合為b。跑最大匹配,沒有匹配的點的個數 n 最大匹配數 就是需要的最少的路徑條數。正確性 二分匹配可以保證每個點頂多只有乙個前...

網路流24題 最小路徑覆蓋 (最小路徑覆蓋)

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