网络流:最大流以及费用流的总结
来源:互联网 发布:网络考试系统破解版 编辑:程序博客网 时间:2024/05/21 17:23
前言:
(终于学会了网络流好开心)网络流是一类问题的统称,实际上很多问题都可以转成网络流来整,所以在此总结一下。
最大流
方法常见的是
dinic
算法的实现是不直接像FF方法所说的以来就找增广路,而是先用bfs将整个图分层,然后再在一层图中的点不算做增广路的路径,这样子的话,避免了找很多额外的边,这样子的话,可以证明复杂度是
而且我们在做的时候,还可以有一个叫做当前弧优化的大法,方法是将肯定不可能的边跳过,这样就大大增快了速度。
下面提供两个版本的
前缀星:
#include <bits/stdc++.h>using namespace std;const int N = 10005;const int M = 100005;const int inf = 1000000000;struct E{int to,cap,nex;}e[M*2];int head[N],ecnt;int dep[N];int iter[N];int n,m,s,t;void adde(int fr,int to,int cap){ e[ecnt] = (E){to,cap,head[fr]}; head[fr] = ecnt++; e[ecnt] = (E){fr,0,head[to]}; head[to] = ecnt++;}void bfs(int s){ memset(dep,-1,sizeof dep); queue <int> q; dep[s] = 0; q.push(s); while (!q.empty()) { int cur = q.front();q.pop(); for (int j=head[cur];j!=-1;j=e[j].nex) { if (e[j].cap >0 && dep[e[j].to] < 0) { dep[e[j].to] = dep[cur] + 1; q.push(e[j].to); } } }}int dfs(int o,int t,int flow){ if (o==t) return flow; for (int &j=iter[o];j!=-1;j=e[j].nex) { if (e[j].cap > 0 && dep[e[j].to] == dep[o] + 1) { int tmpflow = dfs(e[j].to,t,min(flow,e[j].cap)); if (tmpflow > 0) { e[j].cap -= tmpflow; e[j^1].cap += tmpflow; return tmpflow; } } } return 0;}int dinic(int s,int t){ int ansflow = 0; for (;;) { bfs(s); if (dep[t] < 0) return ansflow; for (int i=1;i<=n;i++) iter[i]=head[i]; int f; while ( (f=dfs(s,t,inf)) > 0) { ansflow += f; } }}void init(){ ecnt=0; memset(head,-1,sizeof head);}
邻接表:
#include <bits/stdc++.h>#define pb push_backusing namespace std;const int N = 10005;const int inf = 1000000000;struct E{int to,cap,rev;};vector <E> G[N];int dep[N];int iter[N];int n,m,s,t,e;void adde(int fr,int to,int cap){ G[fr].pb((E){to,cap,G[to].size()}); G[to].pb((E){fr,0,G[fr].size()-1});}void bfs(int s){ memset(dep,-1,sizeof dep); queue <int> q; dep[s] = 0; q.push(s); while (!q.empty()) { int cur = q.front();q.pop(); for (int i=0;i<G[cur].size();i++) { E &e = G[cur][i]; if (e.cap >0 && dep[e.to] < 0) { dep[e.to] = dep[cur] + 1; q.push(e.to); } } }}int dfs(int o,int t,int flow){ if (o==t) return flow; for (int &i=iter[o];i<G[o].size();i++) { E &e = G[o][i]; if (e.cap > 0 && dep[e.to] == dep[o] + 1) { int tmpflow = dfs(e.to,t,min(flow,e.cap)); if (tmpflow > 0) { e.cap -= tmpflow; G[e.to][e.rev].cap += tmpflow; return tmpflow; } } } return 0;}int dinic(int s,int t){ int ansflow = 0; for (;;) { bfs(s); if (dep[t] < 0) return ansflow; memset(iter,0,sizeof iter); int f; while ( (f=dfs(s,t,inf)) > 0) { ansflow += f; } }}
费用流
常见的费用流有两种,一种是求流量为
#include<bits/stdc++.h>using namespace std;const int N = 5002;const int M = 500005;const int inf = 100000;struct E{ int to,cap,cost,flow,next;}e[2*M];int head[N] , ecnt;int pre[N];int dis[N];bool vis[N];int n,m,S,T;void Clear(){ ecnt = 0; memset(head,-1,sizeof head);}void adde(int fr,int to,int cap,int cost){ e[ecnt]=(E){to,cap,cost,0,head[fr]}; head[fr] = ecnt++; e[ecnt]=(E){fr,0,-cost,0,head[to]}; head[to] = ecnt++;}bool SPFA(int s,int t){ memset(vis,0,sizeof vis); memset(dis,127,sizeof dis); memset(pre,-1,sizeof pre); queue <int> q; q.push(s);dis[s] = 0;vis[s]=1; while (!q.empty()) { int cur = q.front();q.pop();vis[cur] = false; for (int j=head[cur];j!=-1;j=e[j].next) { int to = e[j].to; if (dis[to] > dis[cur] + e[j].cost && e[j].cap > e[j].flow ) { dis[to] = dis[cur] + e[j].cost; pre[to] = j; if (!vis[to]) { q.push(to); vis[to] = true; } } } } return pre[t] != -1;}void MCMF (int s,int t,int &maxflow,int &mincost){ maxflow = mincost = 0; while (SPFA(s,t)) { int MIN = inf; for (int j=pre[t]; j!=-1;j=pre[e[j^1].to]) { MIN = min(MIN,e[j].cap - e[j].flow); } for (int j=pre[t]; j!=-1;j=pre[e[j^1].to]) { e[j].flow += MIN; e[j^1].flow -= MIN; mincost += MIN * e[j].cost; } maxflow += MIN; }}
还有一大坑点:建图的时候要从0号边开始,不然他的反边就不是
阅读全文
0 0
- 网络流:最大流以及费用流的总结
- 最小费用最大流总结
- 网络流&费用流总结
- 网络流的征程——最小费用最大流
- [模版] 网络流最大流、费用流
- 求网络的最小费用最大流【好资料】
- 网络最大流和最小费用流
- 网络最大流和最小费用流
- 【最大流+最小费用流】网络扩容
- 网络流 最小费用最大流问题
- 网络流 最小费用最大流
- 网络流-最小费用最大流
- 网络流问题-最小费用最大流
- 网络流-最小费用最大流
- 网络流--最小费用最大流
- [ZJOI2010]网络扩容 (最大流 + 费用流)
- 网络流(最大流、最小费用最大流、有上下界的网络流)
- 网络流-最大流&最小费用最大流
- App启动那点事整理啊
- 页面中文乱码的处理
- 处理 1 counts of IllegalAnnotationExceptions Class has two properties of the same name "ITEM"
- MVP注册登录
- 如何使用memcache缓存
- 网络流:最大流以及费用流的总结
- C语言之对多维数组的简易理解
- MySQL源码安装
- Python 学习笔记-错误记录
- C++矩阵计算库Eigen3之:线性代数与分解
- golang实现简单的反射demo
- C++中动态类型与动态绑定、虚函数、运行时多态的实现
- CSAPP第五章小结
- 数字字符串转换为字母组合的种类数 动态规划