网络流初步最大流(EK算法和Dinic算法进阶)
网络流最大流(network_flows)
网络流是一种类比水流的解决问题的方法,首先我们要明白它解决的是什么样的问题。
比如说最基本的,从水厂通过各种水管到达你家的能有多少水量,每个水管有自己的流量限制,也就是说最多留这么多水。
从1到达3,结果为3。水可以走许多条路,但是最终还是不会大于2到3管道的1,4到3管道的2流量。
在这里只介绍简单的EK算法,解决一般的网络流问题足够用,dinic算法明白其中的含义会用就行,不需要深究。
/*
1.网络流算法用来一个网络中的最大流量,每个水管都有自己的某个限制。
2.其实简单的ek算法就是通过不断寻找增广路,找到增广路中的最小权值然后减去它。
3.记录了前驱,然后倒着走一遍,将所有网络中的边减去这个最小值,再次寻找增广路。
4.增广路其实找一条能到的路就行。
5.这个EK算法可以寻找,复杂度o(v*e*e)。DINIC算法又加上了个dfs,复杂度有所减少。
我的网络流模板出了点问题,这里借用了大佬的模板,看起来比较详细(orz)。
*/
/*测试样例
5 4
1 2 5
1 4 5
2 3 1
4 3 2
2 4 3
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=205;
const int inf=0x7fffffff;
int r[maxn][maxn]; //残留网络,初始化为原图
bool visit[maxn];
int pre[maxn];
int m,n;
bool bfs(int s,int t){//寻找一条从s到t的增广路,若找到返回true,所谓增广路其实就是找s到t的一条路,能找到就行,并记录前驱。int p;queue<int > q;memset(pre,-1,sizeof(pre));memset(visit,false,sizeof(visit));pre[s]=s; visit[s]=true; q.push(s);//从s到twhile(!q.empty()){ /这里用临界矩阵存储边,更好的可以用前向星。//该过程其实就是爆搜。p=q.front();q.pop();for(int i=1;i<=n;i++){if(r[p][i]>0&&!visit[i]){pre[i]=p; //前驱.*划重点啦visit[i]=true;if(i==t) return true; //能到终点q.push(i);}}}return false;
}
int EdmondsKarp(int s,int t){int flow=0,d,i;/*它的思想,如果有增广路(能到的路),因为我记录了前驱所以我可以对这条路倒着走一遍,找到这些边权值最小的那个,然后然所有边的流量减去这个最小值就行。这样就保证了所有流量*/while(bfs(s,t)){d=inf;for(i=t;i!=s;i=pre[i]) d=d<r[pre[i]][i]? d:r[pre[i]][i];for(i=t;i!=s;i=pre[i]){r[pre[i]][i]-=d;//减去最小权值r[i][pre[i]]+=d;//这一步刻画了我这条路实际走了多少水流,可以记录路径。}flow+=d;//加上可以流动的最小流量,然后继续寻找}return flow;
}
int main(){while(scanf("%d%d",&m,&n)!=EOF){int u,v,w;memset(r,0,sizeof(r));///for(int i=0;i<m;i++){scanf("%d%d%d",&u,&v,&w);r[u][v]+=w;}printf("%d\n",EdmondsKarp(1,3));//可以计算1到x的最大流量。}return 0;
}
对上数样例输出为:3 结果显然。
学习网络流需要掌握EK算法的经典思想,dinic算法只给出模板,理解其中含义即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
#define MAX 10100
#define MAXL 210000
#define rg register
#define INF 1000000000
inline int read() //读入优化
{rg int x=0,t=1;rg char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-'){t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}return x*t;
}
int N,M,S,T,Ans=0;
bool vis[MAX];
struct Line
{int v,next,w,fb;
}e[MAXL];
int h[MAX],cnt=1;
int level[MAX];
inline void Add(rg int u,rg int v,rg int w)
{e[cnt]=(Line){v,h[u],w,cnt+1};h[u]=cnt++;e[cnt]=(Line){u,h[v],0,cnt-1};//存反边h[v]=cnt++;
}
inline bool BFS()//分层
{for(int i=1;i<=N;++i)level[i]=0;level[S]=1;queue<int> Q;while(!Q.empty())Q.pop();Q.push(S);while(!Q.empty()){int u=Q.front();Q.pop();for(int i=h[u];i;i=e[i].next){int v=e[i].v;if(e[i].w&&!level[v])//可以增广{level[v]=level[u]+1;Q.push(v);}}}return level[T];//返回是否存在增广路
}
int DFS(rg int u,rg int t,rg int f)//从u到t,当前流量f
{if(u==t||f==0)return f;//到达终点或者已经无法增广了int re=0;//返回值for(int i=h[u];i;i=e[i].next)//访问所有边{rg int v=e[i].v,d;if(e[i].w&&level[v]==level[u]+1)//可以增广,并且满足分层图的要求{d=DFS(v,T,min(f,e[i].w));re+=d;f-=d;e[i].w-=d;//更新流量e[e[i].fb].w+=d;//反边}}return re;
}
inline int Dinic()
{int re=0;while(BFS())re+=DFS(S,T,INF);return re;
}
int main()
{N=read();M=read();S=read();T=read();for(rg int i=1;i<=M;++i){rg int u=read(),v=read(),w=read();Add(u,v,w);}rg int Ans=Dinic();printf("%d\n",Ans);return 0;
}
***五一快乐 想看老师女装 ***
网络流初步最大流(EK算法和Dinic算法进阶)相关推荐
- 网络流初步——最大流费用流
网络流初步--最大流&最小割&费用流 一.基础定义 网络 :一个网络G=(V,E)是一张有向图: 容量 :图中每条边(u,v)∈E都有一个给定的权值c(u,v)被称为容量 源/汇点:两 ...
- 操作系统之存储管理——FIFO算法和LRU算法
操作系统之进程调度--优先权法和轮转法(附上样例讲解) 操作系统之银行家算法-详解流程及案例数据 操作系统之多线程编程-读者优先/写者优先详解 操作系统之存储管理--FIFO算法和LRU算法 操作系统 ...
- 基于Huffman算法和LZ77算法的文件压缩的改进方向
基于Huffman算法和LZ77算法的文件压缩(八) 到这里已经简单实现基于Huffman算法和LZ77算法的文件压缩, GitHub源码:点我 根据基于Huffman算法和LZ77算法的文件压缩(七 ...
- 使用Apriori算法和FP-growth算法进行关联分析
目录 1. 关联分析 2. Apriori原理 3. 使用Apriori算法来发现频繁集 4. 使用FP-growth算法来高效发现频繁项集 5. 示例:从新闻网站点击流中挖掘新闻报道 扩展阅读 系列 ...
- BF算法和KMP算法
给定两个字符串S和T,在主串S中查找子串T的过程称为串匹配(string matching,也称模式匹配),T称为模式.这里将介绍处理串匹配问题的两种算法,BF算法和KMP算法. BF算法 (暴力匹配 ...
- Algorithm:C++语言实现之字符串相关算法(字符串的循环左移、字符串的全排列、带有同个字符的全排列、串匹配问题的BF算法和KMP算法)
Algorithm:C++语言实现之字符串相关算法(字符串的循环左移.字符串的全排列.带有同个字符的全排列.串匹配问题的BF算法和KMP算法) 目录 一.字符串的算法 1.字符串的循环左移 2.字符串 ...
- 若S作主串,P作模式串,试分别写出利用BF算法和KMP算法的匹配过程。
目 录 题目: 百度文库-答案: (1) (2) MOOC标准答案: (1) (2) mooc答案-截图: 数据结构(C语言版)-严蔚敏2007 题目: 设字符串S='aabaabaabaac', ...
- Prim算法和Kruskal算法
Prim算法和Kruskal算法都能从连通图找出最小生成树.区别在于Prim算法是以某个顶点出发挨个找,而Kruskal是先排序边,每次选出最短距离的边再找. 一.Prim(普里姆算法)算法: ...
- 最短路径Dijkstra算法和Floyd算法整理、
转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径-Dijkstra算法和Floyd算法 Dijks ...
最新文章
- 一次失败的机巡平台对接经历分享
- MySQL管理之日志详解
- 鸿蒙上海开发者日直播,华为鸿蒙 OS 开发者日于 4月17 日上海举行
- vue一级分类和耳机分类_?1K411023 岩土分类与不良土质处理方法·2020年一级市政建造师...
- openstack 之 控制节点物理机备份
- 【人工智能】AI如何把招人效率提高四成
- B程序员:讲述三年计算机学习辛酸史
- es6 async函数实例:按顺序完成异步操作
- OpenShift 4 - 基于CPU负载和网络负载的HPA
- Mybatis根据IdType生成不同类型的主键id
- shell if condition
- vue使用element-ui的el-input监听不了回车事件解决
- 转:jQuery Ajax 实例 全解析
- 透过安全事件看软件组成分析SCA
- windows 编译n2n
- 瞳孔特征值提取,blink frequency,fixation frequency,saccad extent, pupil diameter等
- 如何做出 胜过 万龙洲海鲜的 双味腊肠芋头煲
- Socket UDP、TCP 简介
- animate.css 动画库的使用
- 走近“领域特定语言”
热门文章
- 亿方云全国营销中心落户上海,各届大咖挤爆现场!
- 关于QQ的SSO登录
- 如何利用ArcGIS探究环境与生态因子对水体、土壤、大气污染物等影响
- centos系统 关机、重启
- 快速推广拼车小程序的方法,及盈利模式。
- 六大设计模式原则-开闭原则
- JS 数组合并的3种方法(concat(),push(),push.apply())
- 在线课程|存储与计算分离,京东在Elasticsearch上的实践分享
- 嘉兴 机器人仓库 菜鸟_中国最大智能机器人仓库启用,拣货效率至少提升三倍!...
- MySQL和DB2对比