最大流(模板)
来源:互联网 发布:mvc权限管理系统源码 编辑:程序博客网 时间:2024/06/07 01:06
最大流就是建一个反向边,所以说正向边加反向边之和就等于你一开始输入的值,然后找一条增广路,找出最小的cos,把最大流tot加上cos,然后正向边减cos,反向边加cos,这样可以修正错误,因为其实你不用这样流,可你这样流了,就这样直到找不到增广路,就找不到更多的流量了,这时的值就是最大的,其实就是一次一次添流量,直到不能添了
1.EK(Edmond—Karp)算法
也就是广搜版
#include<cstdio>#include<iostream>#include<cstring> using namespace std;const int M=1999999,INF=999999999;int n,m,s,t,used[M];int f[10999][10999];int a[M],pre[M];int d[M];int bfs(int s,int t){ int flow=0; while(1){ memset(a,0,sizeof(a)); memset(d,0,sizeof(d)); a[s]=INF; int h=0,tail=1; d[1]=s; while(h<tail){ h++; int x=d[h]; for(int i=1;i<=n;i++) if(f[x][i]&&!a[i]) { pre[i]=x; a[i]=min(a[x],f[x][i]); d[++tail]=i; } } if(!a[t]) break; for(int i=t;i!=s;i=pre[i]) { f[pre[i]][i]-=a[t]; f[i][pre[i]]+=a[t]; } flow+=a[t]; } return flow;}int main(){ scanf("%d%d%d%d",&n,&m,&s,&t); for(int i=1;i<=m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); f[x][y]+=z; } int d=bfs(s,t); printf("%d",d); return 0;}
2.Ford-Fulkerson算法
也就是深搜版
这里用的链表
位运算是为了找反向边
#include<cstdio>#include<iostream>#include<cstring> using namespace std;const int M=199999,INF=999999999;int n,m,s,t,used[M];int nex[M],head[M],cos[M],to[M],tot;int add(int x,int y,int z){ cos[tot]=z; nex[++tot]=head[x]; to[tot]=y; head[x]=tot;}int dfs(int s,int t,int f){ if(s==t) return f; for(int i=head[s];i;i=nex[i]){ int tmp=to[i]; if(cos[i-1]&&!used[tmp]){ used[tmp]=1; int d=dfs(tmp,t,min(cos[i-1],f)); if(d>0){ cos[i-1]-=d; cos[(i-1)^1]+=d; return d; } } } }int maxflow(int s,int t){ int flow=0; while(1){ memset(used,0,sizeof(used)); int d=dfs(s,t,INF); if(d==0)return flow; flow+=d; }}int main(){ scanf("%d%d%d%d",&n,&m,&s,&t); for(int i=1;i<=m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,0); } int d=maxflow(s,t); printf("%d",d); return 0;}
3.还有Dinic算法
就是综合以上两种方法,先用bfs建一个有层次的图,同一个层次的一定不是增广路,再用dfs找减少多余同层次的,就比较省事
#include<cstdio>#include<iostream>#include<cstring> #include<queue>using namespace std;const int M=199999,INF=999999999;int n,m,s,t,used[M],deep[M];int nex[M],head[M],cos[M],to[M],tot;int add(int x,int y,int z){ cos[tot]=z; nex[++tot]=head[x]; to[tot]=y; head[x]=tot;}int bfs(int s,int t){ queue< int > d; memset(deep,-1,sizeof(deep)); deep[s]=0; d.push(s); while(!d.empty()){ int x=d.front(); d.pop(); for(int i=head[x];i;i=nex[i]){ int tmp=to[i]; if(cos[i-1]&&deep[tmp]==-1){ deep[tmp]=deep[x]+1; d.push(tmp); } } } return deep[t]!=-1; } int dfs(int s,int t,int f){ if(s==t) return f; for(int i=head[s];i;i=nex[i]){ int tmp=to[i]; if(cos[i-1]&&deep[s]+1==deep[tmp]){ int d=dfs(tmp,t,min(cos[i-1],f)); if(d>0){ cos[i-1]-=d; cos[(i-1)^1]+=d; return d; } } } }int maxflow(int s,int t){ int flow=0; while(bfs(s,t)){ while(1) { int d=dfs(s,t,INF); if(d==0)break; flow+=d; } } return flow;}int main(){ scanf("%d%d%d%d",&n,&m,&s,&t); for(int i=1;i<=m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,0); } int d=maxflow(s,t); printf("%d",d); return 0;}
1 0
- 最大流(模板)
- 最大流(模板)
- 最大流模板(poj3469)
- 最大流模板(Dinic)
- p1273最大流(模板)
- poj3281最大流(模板)
- 网络流(最大流+模板)
- 网络最大流(dinic)【模板】
- 网络最大流(SAP)【模板】
- 最大流模板(Edmonds-Karp)
- 最大流模板(Dinic算法)
- 最大流模板(Edmonds-Karp)
- 网络最大流(SAP)模板
- 网络最大流(dinic)模板
- 最大流SAP模板(邻接矩阵)
- 最大流模板(学习中)
- hdu3549Flow Problem(最大流 模板题)
- 最小费用最大流(讲解+模板)
- Xpath解析之:几个常纠结的节点选取语法总结
- 数据结构Java实现05----栈:顺序栈和链式堆栈
- virtio_blk 通过写virtqueue 出发中断通知qemu后端
- Android—子线程更新UI问题( java.lang.RuntimeException: Can't create handler inside thread that has not cal)
- fiddler抓包
- 最大流(模板)
- mysql注释解释详见
- Linux MySQL修改密码时 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
- SSH三大框架的工作原理及流程
- 配置可以上网的Host-only网络
- java开发规范
- 用NLTK进行自然语言处理的项目
- c++11新特性--auto的使用
- money or life