最大流EK和Dinic算法

EK算法

最朴素的求最大流的算法。
做法:不停的寻找增广路,直到找不到为止

代码如下:

@Frosero
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#define INF 0x3f3f3f3f using namespace std;
int n,m;
int cap[202][202],flow[202][202],mf[202],pre[202];
//cap为网络的容量 flow为现在的流量
//mf[i]为原点到点i的最大流量 pre[i]为增广路上i点上一个点 int EK(int s,int t){
memset(flow,0,sizeof(flow));
queue<int>q;
int ans = 0;
while(1){
while(!q.empty()) q.pop(); q.push(s);
memset(mf,0,sizeof(mf));
mf[1] = INF;
while(!q.empty()){
int u = q.front(); q.pop();
for(int i=1;i<=m;i++)if(!mf[i] && flow[u][i] < cap[u][i]){
pre[i] = u;
q.push(i);
mf[i] = min(mf[u],cap[u][i] - flow[u][i]);
}
}
if(mf[t] == 0) break;
ans += mf[t];
for(int i=t;i!=s;i=pre[i]){
flow[pre[i]][i] += mf[t];
flow[i][pre[i]] -= mf[t];
}
}
return ans;
} int main(){
while(scanf("%d %d",&n,&m)!=EOF){
memset(cap,0,sizeof(cap));
memset(flow,0,sizeof(flow));
int u,v,w;
while(n--){
scanf("%d %d %d",&u,&v,&w);
cap[u][v] += w;
}
printf("%d\n",EK(1,m));
}
}

Dinic算法

Dinic的优化部分就是给残留网络生成一个层次图,然后尽量的利用层次图后再形成新的层次图。

理论上Dinic和EK算法的时间复杂度差不多,但是事实上Dinic算法要好得多。

代码如下:

@Frosero
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#define INF 0x3f3f3f3f using namespace std; int n,m,flow[202][202],cap[202][202];
int dis[202];
//flow为现在的流量 cap为网络的容量
//dis为点的层次 bool bfs(){ //形成层次图
memset(dis,-1,sizeof(dis));
dis[1] = 0;
queue<int>q; q.push(1);
while(!q.empty()){
int u = q.front(); q.pop();
for(int i=1;i<=m;i++)if(dis[i] == -1 && flow[u][i] < cap[u][i]){
dis[i] = dis[u] + 1;
q.push(i);
}
}
if(dis[m] == -1) return false;
else return true;
} int dfs(int s = 1,int f = INF){ //利用层次图不断寻找增广路
if(s == m || f == 0) return f;
int ans = 0;
for(int i=1;i<=m;i++)if(dis[i] == dis[s] + 1){
int a = dfs(i,min(f,cap[s][i] - flow[s][i]));
if(a == 0) continue;
flow[s][i] += a;
flow[i][s] -= a;
ans += a;
f -= a;
if(f <= 0) break;
}
return ans;
} int dinic(){ //Dinic主过程
int ans = 0;
while(bfs()){
ans += dfs();
}
return ans;
} int main(){
while(scanf("%d %d",&n,&m)!=EOF){ //本代码假设1为原点 m为汇点
memset(flow,0,sizeof(flow));
memset(cap,0,sizeof(cap));
int u,v,w;
while(n--){
scanf("%d %d %d",&u,&v,&w);
cap[u][v] += w;
}
printf("%d\n",dinic());
}
return 0;
}

最大流EK和Dinic算法的更多相关文章

  1. POJ1273:Drainage Ditches(最大流入门 EK,dinic算法)

    http://poj.org/problem?id=1273 Description Every time it rains on Farmer John's fields, a pond forms ...

  2. POJ 1273 - Drainage Ditches - [最大流模板题] - [EK算法模板][Dinic算法模板 - 邻接表型]

    题目链接:http://poj.org/problem?id=1273 Time Limit: 1000MS Memory Limit: 10000K Description Every time i ...

  3. 最大流EK算法/DINIC算法学习

    之前一直觉得很难,没学过网络流,毕竟是基础知识现在重新来看. 定义一下网络流问题,就是在一幅有向图中,每条边有两个属性,一个是cap表示容量,一个是flow 表示流过的流量.我们要求解的问题就是从S点 ...

  4. 网络流入门—用于最大流的Dinic算法

    "网络流博大精深"-sideman语 一个基本的网络流问题 最早知道网络流的内容便是最大流问题,最大流问题很好理解: 解释一定要通俗! 如右图所示,有一个管道系统,节点{1,2,3 ...

  5. 网络(最大)流初步+二分图初步 (浅谈EK,Dinic, Hungarian method:]

    本文中  N为点数,M为边数: EK: (brute_force) : 每次bfs暴力找到一条增广路,更新流量,代码如下 : 时间复杂度:O(NM²): #include<bits/stdc++ ...

  6. 【最大流之Dinic算法】POJ1273 【 & 当前弧优化 & 】

    总评一句:Dinic算法的基本思想比较好理解,就是它的当前弧优化的思想,网上的资料也不多,所以对于当前弧的优化,我还是费了很大的功夫的,现在也一知半解,索性就写一篇博客,来发现自己哪里的算法思想还没理 ...

  7. HDU1532最大流 Edmonds-Karp,Dinic算法 模板

    Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...

  8. Dinic算法----最大流常用算法之一

    ——没有什么是一个BFS或一个DFS解决不了的:如果有,那就两个一起. 最大流的$EK$算法虽然简单,但时间复杂度是$O(nm^2)$,在竞赛中不太常用. 竞赛中常用的$Dinic$算法和$SAP$, ...

  9. 最大流——EK算法

    一.算法理论 [基本思想] 反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-流量]的最小值delta,若无,则结束.在寻找增广路径时,可以用BFS来找,并且更新残留网络的值(涉 ...

随机推荐

  1. 【leetcode】927. Three Equal Parts

    题目如下: Given an array A of 0s and 1s, divide the array into 3 non-empty parts such that all of these ...

  2. shell倒计时下班时间

    #!/bin/sh offWorkTime="19:00:00" offWorkHour=${offWorkTime::} offWorkMinute=${offWorkTime: ...

  3. tar的具体参数和用法!

    tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...

  4. context和getApplicationContext()的区别

    在android中常常会遇到与context有关的内容 浅论一下 context : 在语句 AlertDialog.Builder builder = new AlertDialog.Builder ...

  5. HTML5: HTML5 服务器发送事件(Server-Sent Events)

    ylbtech-HTML5: HTML5 服务器发送事件(Server-Sent Events) 1.返回顶部 1. HTML5 服务器发送事件(Server-Sent Events) HTML5 服 ...

  6. 61、Queueable接口

    public with sharing class QueueableSample implements Queueable{ private List<String> Name{get; ...

  7. 一个python练习

    问题描述: 有一对兔子,每隔3个月就生一对兔子,生下来的兔子也是每隔3个月就生兔子,以此类推... 用python模拟出来: #!/usr/bin/python3 import random impo ...

  8. select change()

    $(".learnStageId").change(function(){ var id = $(this).val(); $(".gradeId").find ...

  9. Oracle之Group by和Having-----转了

    在介绍GROUP BY 和 HAVING 子句前,我们必需先讲讲sql语言中一种特殊的函数:聚合函数,例如SUM, COUNT, MAX, AVG等.这些函数和其它函数的根本区别就是它们一般作用在多条 ...

  10. NIO浅析(一)

    一:NIO与IO的区别 1.NIO面对的是缓冲区,IO面对的是流 2.NIO是非阻塞的,IO是阻塞的 3.NIO中引入了选择器 二:既然NIO面对的是缓冲区,那就先来了解缓冲区 1.NIO中Buffe ...