最大流EK和Dinic算法
最大流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算法的更多相关文章
- POJ1273:Drainage Ditches(最大流入门 EK,dinic算法)
http://poj.org/problem?id=1273 Description Every time it rains on Farmer John's fields, a pond forms ...
- POJ 1273 - Drainage Ditches - [最大流模板题] - [EK算法模板][Dinic算法模板 - 邻接表型]
题目链接:http://poj.org/problem?id=1273 Time Limit: 1000MS Memory Limit: 10000K Description Every time i ...
- 最大流EK算法/DINIC算法学习
之前一直觉得很难,没学过网络流,毕竟是基础知识现在重新来看. 定义一下网络流问题,就是在一幅有向图中,每条边有两个属性,一个是cap表示容量,一个是flow 表示流过的流量.我们要求解的问题就是从S点 ...
- 网络流入门—用于最大流的Dinic算法
"网络流博大精深"-sideman语 一个基本的网络流问题 最早知道网络流的内容便是最大流问题,最大流问题很好理解: 解释一定要通俗! 如右图所示,有一个管道系统,节点{1,2,3 ...
- 网络(最大)流初步+二分图初步 (浅谈EK,Dinic, Hungarian method:]
本文中 N为点数,M为边数: EK: (brute_force) : 每次bfs暴力找到一条增广路,更新流量,代码如下 : 时间复杂度:O(NM²): #include<bits/stdc++ ...
- 【最大流之Dinic算法】POJ1273 【 & 当前弧优化 & 】
总评一句:Dinic算法的基本思想比较好理解,就是它的当前弧优化的思想,网上的资料也不多,所以对于当前弧的优化,我还是费了很大的功夫的,现在也一知半解,索性就写一篇博客,来发现自己哪里的算法思想还没理 ...
- HDU1532最大流 Edmonds-Karp,Dinic算法 模板
Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- Dinic算法----最大流常用算法之一
——没有什么是一个BFS或一个DFS解决不了的:如果有,那就两个一起. 最大流的$EK$算法虽然简单,但时间复杂度是$O(nm^2)$,在竞赛中不太常用. 竞赛中常用的$Dinic$算法和$SAP$, ...
- 最大流——EK算法
一.算法理论 [基本思想] 反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-流量]的最小值delta,若无,则结束.在寻找增广路径时,可以用BFS来找,并且更新残留网络的值(涉 ...
随机推荐
- php wordwrap()函数 语法
php wordwrap()函数 语法 wordwrap()函数怎么用? wordwrap()函数表示按照指定长度对字符串进行折行处理,语法是wordwrap(string,width,break,c ...
- LayuiAdmin 滚动条设置问题解决
LayuiAdmin 滚动条设置问题解决 今天在使用LayuiAdmin(单页版),发现通过: $("html,body").animate({"scrollTop&qu ...
- BZOJ 4568: [Scoi2016]幸运数字(倍增+线性基)
传送门 解题思路 异或最大值肯定线性基了,树上两点那么就倍增搞一搞,就维护每个点到各级祖先的线性基,时间复杂度\(O(nlog^3n)\),并不知道咋过去的. 代码 #include<iostr ...
- SQL Server数据库备份&还原
一.备份 1.登录数据库 2.找到要还原的数据库 右键-任务-备份-添加(路径只写一个,刚开始二个总是报错)-确定 二.还原数据库 这个之间报错了二次 1.报错1:备份集中的数据库与现有数据库“XXX ...
- SQL必知必会——插入数据(十五)
1.数据插入 INSERT用来将行插入(或添加)到数据库表.插入有几种方式: 插入完整的行插入行的一些部分插入某些查询的结果注意:1.使用INSERT语句可能需要客户端/服务端DBMS中的特定安全权限 ...
- spring MVC 返回值信息和ResponseBody的响应json数据
spring mvc的界面返回: 如果我们定义的返回类型是String 那么我们返回的时候直接写入 我们的界面的名字就可以了 springmvc会自动去找到我们的界面,如果是void类型的返回那么 ...
- Jeecg_Jflow整合记录
系统组织机构 t_s_deparselect * from t_s_departselect * from t_s_depart where id='402888fd6a8c24e9016a8c531 ...
- Process Hacker源码中的用户态hook的做法
processhacker-code-5632\1.x\trunk\NProcessHacker\hook.h typedef struct _PH_HOOK { PVOID Function; PV ...
- JAVA中一个汉字占多少个字符(转载)
1.先说重点: 不同的编码格式占字节数是不同的,UTF-8编码下一个中文所占字节也是不确定的,可能是2个.3个.4个字节: 2.以下是源码: 1 @Test 2 public void test1() ...
- RedisTemplate序列号自增id(当前日期+序列号)
话不多上,直接上码 public class TestService { @Resource RedisTemplate<String, Object> redisTemplate; pu ...