網路流模板與經典模型

2022-06-28 11:33:08 字數 2718 閱讀 4917

1.模板

dinic模板(常規的最大流模板,演算法效率能滿足大部分題)

#include#include#include#includeusing namespace std;

#define ll long long

const ll n=10007;

const ll m=200007;

const ll inf=1e18;

ll n,m,s,t;

ll h[n],e[m],f[m],ne[m],tot;

ll d[n],cur[n];

queuesa;

void add(ll u,ll v,ll z)

bool bfs()

sa.push(to);

}} }

return false;

}ll dfs(ll p,ll now)e[maxm<<2];

int n,m;

int head[maxn],cnt=1,gap[maxn],last[maxn],d[maxn],que[maxn],ql,qr;

void init()

void add(int u,int to,int w)

int aug(int x,int s,int t,int mi)

}if(!(--gap[d[x]]))d[s]=t+1;

++gap[++d[x]],last[x]=head[x];

return flow;

}int dinic(int s,int t)}}

int ans=aug(s,s,t,inf);

while(d[s]<=t)ans+=aug(s,s,t,inf);

return ans;

}

最小費最大流
#

include using namespace std;

#define ll long long

const int n=5007;

const ll inf=1e18;

#define pii pair #define fr first

#define sc second

struct madoka;

ll v=0,h[n],dis[n],pv[n],pe[n];

vectorg[n];

inline void init(ll n)

v=n;

ld.clear();

} inline void add(ll u,ll v,ll f,ll c));

g[v].push_back();

} pii dinic(ll s,ll t,ll flow));

while(!q.empty())}}

if(dis[t]==inf) break;

for(ll i=0;i<=v;i++) h[i]+=dis[i];

newflow=flow;

for(ll x=t;x!=s;x=pv[x]) newflow=min(newflow,g[pv[x]][pe[x]].f);

flow-=newflow,flow+=newflow,cost+=newflow*h[t];

for(ll x=t;x!=s;x=pv[x])

} return ;

}}a;

int main()

pii ans=a.dinic(s,t,inf);

}}

2.常用模型

(1)二分圖上的最大流

飛行員配對

簡單,建超級源點與超級匯點,連上邊,邊權容量為1,很明顯最大匹配數就是最大流。

(2)多源匯最大流

多源匯最大流

簡單,建超級源點與超級匯點,分別所有源點,與匯點,邊權無限,跑最大流。

(3)拆點

餐飲中等,當點上有點權控制流量時,而跑普通的最大流無法滿足點權的限制,此時將點視為邊,即將點拆分成兩點,增加一條邊出來控制流量,比較考驗建圖能力。

(4)最小割

模板中等,一張圖的最小割等於其最大流,很多題目較抽象,無法理解成求最大流,但能轉換成最小割,便可通過求最大流算出最小割。、

(5)上下界的網路

困難,抽象難想,不好建模。

上下界可行流

將所有邊分成兩條,容量分別是下界,上界-下界。

下界的邊是必須滿足的,故將下界邊的出點與匯點連,入點與源點連。

源點可以提供無限流量,讓所有下界都充滿水,檢查匯點,若匯點流出的值小於所有下界的和,那麼說明下界管子沒流滿水,就無可行流,反之合法。

有源匯上下界最大流

加匯點連一條去源點的邊,便變成了無向圖,按上方法求可行流,在求源匯最大流,即在滿足可行流的情況下求最大流,注意去除新源匯的反邊流量防止其退流,使其變成非可行流。

有源匯上下界最小流

和上題一樣,最後只要求匯點到源點的最大流,看能退多少流回去就行。

(6)最大權閉合子圖

最大獲利

困難,公式推導太抽象,這裡只說我的理解。

將負權點連向匯點,容量為點權*(-1)。

將正權點連向源點,容量為點權。

正負點權間邊,容量無限。

考慮最小割,很明顯只會切源點與正點的連線,或匯點與負點的連線。

首先,先假設正權的點我全要,此時我便要支付必須要選的負點的費用。

而最小割,若切在負匯邊上,說明我支付了該負點的費用。

若切在正源邊上,說明要獲取此正點太虧,把正點權還回去實現反悔。

所以答案就所有正點權和減去最小割。

網路流模板

鄰接矩陣 include include include using namespace std const int inf 1 30 const int point num 300 int cap point num point num dist point num gap point num 初...

網路流模板

最大流 最小割 演算法 最小割就是刪掉權值最小的邊讓源點和匯點分別分在兩個不連通的集合 就是把圖分成兩個集合,保證源點和匯點不連通,可以解決刪掉權值最小的邊刻意讓某些點和另外點孤立,也就是堵住前面點到匯點的去路 增廣路edmondskarp演算法 n m 2 n是點數,m是有向邊數 define r...

網路流模板

最大流 include include include include include include using namespace std define clr a x memset a x sizeof a const int maxm 1005 const int maxn 20 const...