网络流模板
作者:互联网
网络流
没有详细的分析解释,只有两个模板,若要学习网络流知识,还请前往它站
网络\(G = (E , V)\)是一张有向图,其中每条边都有一个流量c,还有两个特殊点S(源点),T(汇点)。设\(f(x,y)\)为定义在节点二元组\((x,y\in V)\)的流函数,满足
- 容量限制 f(x,y) <= c(x,y)
- 斜对称 f(x,y) + f(y,x) = 0
- 流量守恒 \(\forall u \neq S , T. \ \ \sum_{(u,x)\in E}f(u,x) = \sum_{(x,v) \in E} f(x,v)\)
\(\sum_{(S,x)\in E}f(S,x)\) 称为全图的流量
EK
增广路指从S到T的一条剩余容量不为零的路径
求最大流的过程就是不断求增广路的过程。
EK算法就是不断bfs求增广路然后修改剩余容量
复杂度\(O(nm^2)\)实际跑不满,可以处理\(1e3 \thicksim 1e4\)的数据
#include<iostream>
#include<queue>
using namespace std;
const int N = 205 , M = 5005 , inf = 214748647;
int n , m , S , T , Cnt = 1;
int head[N] , f[N] , pre[N] , vis[N];
long long Answer;
struct edge{ int v , c , nex; }e[M << 1];
inline void add(int u , int v , int c)
{
e[++Cnt].v = v; e[Cnt].c = c; e[Cnt].nex = head[u]; head[u] = Cnt;
}
bool Bfs()
{
queue<int> q;
for(int i = 1 ; i <= n ; ++i) vis[i] = 0;
f[S] = inf; vis[S] = 1; q.push(S);
while(q.size())
{
int x = q.front(); q.pop();
if(x == T) return true;
for(int i = head[x] ; i ; i = e[i].nex) if(e[i].c && !vis[e[i].v])
{
f[e[i].v] = min(f[x] , e[i].c);
pre[e[i].v] = i; vis[e[i].v] = 1; q.push(e[i].v);
}
}
return false;
}
void Update()
{
int x = T , i;
Answer += f[T];
while(x != S)
{
i = pre[x];
e[i].c -= f[T]; e[i^1].c += f[T];
x = e[i^1].v;
}
}
int main()
{
int u , v , c;
cin >> n >> m >> S >> T;
for(int i = 1 ; i <= m ; ++i)
{
cin >> u >> v >> c;
add(u , v , c);
add(v , u , 0);
}
while(Bfs()) Update();
cout << Answer << '\n';
return 0;
}
Dinic
残量网络: 由剩余容量大于0的边构成的网络
分层图: d[x]表示从S到x的长度
算法,先bfs构造分层图,然后在分层图上dfs,回溯是更新流量
#include<iostream>
#include<queue>
using namespace std;
const int N = 205 , M = 5005 , inf = 214748647;
int n , m , S , T , Cnt = 1;
int head[N] , cur[N] , d[N];
long long Answer;
struct edge{ int v , c , nex; }e[M << 1];
inline void add(int u , int v , int c)
{
e[++Cnt].v = v; e[Cnt].c = c; e[Cnt].nex = head[u]; head[u] = Cnt;
}
queue<int> q;
bool Bfs()
{
for(int i = 1 ; i <= n ; ++i) d[i] = 0;
q.push(S); d[S] = 1;
while(q.size())
{
int x = q.front(); q.pop();
for(int i = head[x] ; i ; i = e[i].nex) if(e[i].c && !d[e[i].v])
{
d[e[i].v] = d[x] + 1; q.push(e[i].v);
}
}
return d[T];
}
long long Dfs(int x , int flow)
{
if(x == T || flow == 0) return flow;
long long res = 0;
for(int &i = cur[x] ; i ; i = e[i].nex)
{
int v = e[i].v;
if(e[i].c && d[v] == d[x] + 1)
{
long long k = Dfs(v , min(e[i].c , flow));
if(k)
{
flow -= k; res += k; e[i].c -= k; e[i^1].c += k;
if(!flow) return res;
}
}
}
return res;
}
int main()
{
int u , v , c;
cin >> n >> m >> S >> T;
for(int i = 1 ; i <= m ; ++i)
{
cin >> u >> v >> c;
add(u , v , c);
add(v , u , 0);
}
long long tmp;
while(Bfs())
{
for(int i = 1 ; i <= n ; ++i) cur[i] = head[i];
while(tmp = Dfs(S , inf)) Answer += tmp;
}
cout << Answer << '\n';
return 0;
}
标签:int,网络,long,Bfs,add,include,模板 来源: https://www.cnblogs.com/R-Q-R-Q/p/16435949.html