網路流模板

2021-06-25 19:57:25 字數 3685 閱讀 3398

===【最大流(最小割)演算法】===

最小割就是刪掉權值最小的邊讓源點和匯點分別分在兩個不連通的集合(就是把圖分成兩個集合,保證源點和匯點不連通,可以解決刪掉權值最小的邊刻意讓某些點和另外點孤立,也就是堵住前面點到匯點的去路)

【增廣路edmondskarp演算法(n*m^2)】n是點數,m是有向邊數

#define rep(i,a,n) for(int i = a; i < n; i++)

#define clc(a,b) memset(a,b,sizeof(a))

#define maxn 410

#define inf 0x3f3f3f3f

struct ek

}; int a[maxn], p[maxn];

vectorg[maxn];

vectoredge;

void init(int n)

void add_edge(int from, int to, int cap)

int e_k(int st, int ed)

}if (a[ed]) break;

}if (!a[ed]) break;

for (int u = ed; u != st; u = edge[p[u]].from)

ans += a[ed];

} return ans;

}}ek;

【dinic演算法(n^2*m)】

#define rep(i,a,n) for(int i = a; i < n; i++)

#define repe(i,a,n) for(int i = a; i <= n; i++)

#define per(i,n,a) for(int i = n; i >= a; i--)

#define clc(a,b) memset(a,b,sizeof(a))

#define inf 0x3f3f3f3f

typedef long long ll;

#define maxn 40010

#define maxm 400100//記得兩倍 有反向邊

struct dinic

}edge[maxm];

int head[maxn], tol, s,t,d[maxn],cur[maxn];

bool vis[maxn];

void init()

void add_edge(int u, int v, int cap)

bool bfs()

}} return vis[t];

} int dfs(int u, int a)

}return flow;

} int maxflow(int s, int t)

return flow;

}}dinic;

【isap 遞迴簡潔版(n^2*m)】

#define rep(i,a,n) for(int i = a; i < n; i++)

#define repe(i,a,n) for(int i = a; i <= n; i++)

#define per(i,n,a) for(int i = n; i >= a; i--)

#define clc(a,b) memset(a,b,sizeof(a))

#define inf 0x3f3f3f3f

typedef long long ll;

#define maxn 20

#define maxm 2010//記得兩倍 有反向邊

struct isap

}edge[maxm];

int head[maxn], tol;

void init(int n)

void add_edge(int u, int v, int cap)

int dfs(int u, int a)

else if(d[s] >= n || !a)

return ans;

}mi = min(mi, d[e.v]);

} if(!ans)

num[d[u] = mi+1]++;

} return ans;

} int maxflow(int s, int t)

}isap;

【isap + bfs初始化 + 棧優化(n^2*m)】

#define rep(i,a,n) for(int i = a; i < n; i++)

#define clc(a,b) memset(a,b,sizeof(a))

#define maxn 55

#define inf 0x3f3f3f3f

struct isap

};int p[maxn]/*可增廣的上一條弧*/, num[maxn]/*距離標號計數*/, d[maxn]/*起點到i距離*/,cur[maxn]/*當前弧下標*/;

int n, s, t;//節點數,邊數,起點,終點

vectorg[maxn];//鄰接表

vectoredge;

bool vis[maxn];

void init(int n)

void add_edge(int from, int to, int cap)

int augment()

x = t;

while(x != s)

return a;

}bool bfs()}}

return vis[s];

}int maxflow(int s, int t)

int ok = 0,sz = g[x].size();

rep(i,cur[x],sz)

}if(!ok)

if(--num[d[x]] == 0) return flow;//gap優化

num[d[x] = sum+1]++;

cur[x] = 0;

if(x != s) x = edge[p[x]].from;}}

return flow;

}}isap;

===【最小費用最大流演算法】===

【運用類似ek演算法(n*m^2)】

struct mcmf

}; vectoredge;

vectorg[maxn];

bool inq[maxn];

int d[maxn]/*spfa*/, p[maxn]/*上一條弧*/, a[maxn]/*可改進量*/;

void init(int n)

void add_edge(int from, int to, int cap, int cost)

bool spfa(int s, int t, int& flow, ll& cost)

}} if(inf == d[t]) return false;

flow += a[t];

cost += (ll)d[t]*(ll)a[t];

for(int u = t; u != s; u = edge[p[u]].from)

return true;

} //需要保證初始網路沒有負圈,返回最大流量,cost才是最小花費

int mincostmaxflow(int s, int t, ll & cost)

}mcmf;

網路流模板

鄰接矩陣 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 初...

網路流模板

最大流 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...

網路流模板

dinic struct edge vector g max v int level max v int iter max v 當前弧優化 void add edge int from,int to,int cap 通過bfs計算從源點出發的距離標號 void bfs int s 通過dfs尋找增廣...