考慮最終的那些覆蓋路徑的樣子是什麼,顯然是很多點和很多鏈(廢話),但是學過生物必修一肽鏈和蛋白質的人都能發現,路徑條數=\(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的最小路徑覆...