网络流问题:

我自己理解,在流网络中,在不违背容量限制的条件下,解决各种从源点到汇点的问题。

ISAP算法概念:

据说不会有卡ISAP时间的题目………时间复杂度O(E^2*V)

首先原理都是基于不断寻找增广路,属于增广路方法。普通的SAP算法比如EK算法,Dinic 算法,由于在寻找增广路时,都需要先进行BFS,BFS时间复杂度O(E),所以总的时间复杂度最坏情况达到O(VE2)。

ISAP算法的优化在于距离标号,即每个顶点到达终点 t 的距离。所以可以在遍历的过程中,就建立了一个分层网络,不需要每一次都对全图进行BFS遍历,提高了效率。

算法实现过程:

1.反向 BFS 初始化所有顶点的距离标号。(由于在在循环中自动建立起分层网络,所以不需要进行也可以,据大神博客,有无相差5%的时间左右)。

2.当前顶点 V为终点时增广。

3. 当前顶点有满足 dist[V] = dist[j] + 1 的出弧时前进。

4. 当前顶点无满足条件的出弧时重标号并回退一步。整个循环当源点 s 的距离标号 dist[s] >= n 时结束。对V点的重标号操作为 dist[i] = 1 + min。min为对于V相邻的dis最小(离汇点最近)的点。

先对几个概念的理解:

1.增广路:假设我们已经找到了一条从源点到汇点的路径,如果这条路上得每一段路径的此时的流量都小于容量,那么可以确定一个最小的差delta,那么每一段加上delta,就可以得到一个更大的流,即增广路。

2.距离标号:就是某个点到汇点的最少的弧的数量(即边权值为1时某个点到汇点的最短路径长度)。设点i的标号为level[i],那么如果将满足level[i]=level[j]+1的弧(i,j)叫做允许弧 ,且增广时只走允许弧。

3.反向边:简单的说反向边的作用就是给程序一个可以后悔的机会。直接说原因,寻找最优增广路(最大流)其实是有一定的顺序,但是程序不可能预知,所以在每一次对于流量的操作,都 在反方向增加一个回溯流量。

即 map[pre[i]][i]-=aug;

map[i][pre[i]]+=aug;

4.断层(GAP优化思想):gap[i]数组表示距离标号为i的点有多少个,如果到某一点没有符合距离标号的允许弧,那么需要修改距离标号来找到增广路。如果重标号使得gap数组中原标号数目变为0,即修改则无法到达,则算法结束。

代码:

具体还是一遍遍看代码理解….

例题:hdu 1532http://acm.hdu.edu.cn/showproblem.php?pid=1532

邻接矩阵版:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 222
#define inf 100000000+1000
int map[MAXN][MAXN];//存图
int pre[MAXN];//记录当前点的前驱
int level[MAXN];//记录距离标号
int gap[MAXN];//gap常数优化
int NV,NE; //可以加入一个反向的BFS,优化些许时间。 //入口参数vs源点,vt汇点
int SAP(int vs,int vt){
memset(pre,-1,sizeof(pre));
memset(level,0,sizeof(level));
memset(gap,0,sizeof(gap));
gap[0]=vt;
int v,u=pre[vs]=vs,maxflow=0,aug=inf;
while(level[vs]<vt)
{
//寻找可行弧
for(v=1;v<=vt;v++){
if(map[u][v]>0&&level[u]==level[v]+1){
break;
}
}
if(v<=vt){
pre[v]=u;
u=v;
if(v==vt){
aug=inf;
//寻找当前找到的一条路径上的最大流
for(int i=v;i!=vs;i=pre[i]){
if(aug>map[pre[i]][i])aug=map[pre[i]][i];
}
maxflow+=aug;
//更新残留网络
for(int i=v;i!=vs;i=pre[i]){
map[pre[i]][i]-=aug;
map[i][pre[i]]+=aug;
}
u=vs;//从源点开始继续搜
}
}
else {
//找不到可行弧
int minlevel=vt;
//寻找与当前点相连接的点中最小的距离标号
for(v=1;v<=vt;v++){
if(map[u][v]>0&&minlevel>level[v]){ //离vt最近的点
minlevel=level[v];
}
}
gap[level[u]]--;//(更新gap数组)当前标号的数目减1;
if(gap[level[u]]==0)
break;//出现断层 如果出现断层,则该点为一个唯一点,后退也没有意义
level[u]=minlevel+1;
gap[level[u]]++;
u=pre[u]; //相当于后退一步
}
}
return maxflow;
} int main(){
int n,m,u,v,cap;
while(~scanf("%d%d",&m,&n)){
memset(map,0,sizeof(map));
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&cap);
map[u][v]+=cap;
}
printf("%d\n",SAP(1,n));
}
return 0;
}

网络流 ISAP算法的更多相关文章

  1. 网络流-最大流问题 ISAP 算法解释(转自Renfei Song's Blog)

    网络流-最大流问题 ISAP 算法解释 August 7, 2013 / 编程指南 ISAP 是图论求最大流的算法之一,它很好的平衡了运行时间和程序复杂度之间的关系,因此非常常用. 约定 我们使用邻接 ...

  2. ISAP 算法的学习

    http://www.renfei.org/blog/isap.html 算法与数学 网络流-最大流问题 ISAP 算法解释 2013-08-07Renfei Song 2 条评论 内容提要 [隐藏] ...

  3. ISAP算法对 Dinic算法的改进

    ISAP算法对 Dinic算法的改进: 在刘汝佳图论的开头引言里面,就指出了,算法的本身细节优化,是比较复杂的,这些高质量的图论算法是无数优秀算法设计师的智慧结晶. 如果一时半会理解不清楚,也是正常的 ...

  4. P3376 【模板】网络最大流( Edmonds-krap、Dinic、ISAP 算法)

    P3376 [模板]网络最大流( Edmonds-krap.Dinic.ISAP 算法) 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入格式 第一行包含四个正整数N.M.S ...

  5. HDOJ-3416(最大流+最短路+ISAP算法+向前星dijikstra算法+如何判断一条边是否在最短路中)

    Marriage Match IV HDOJ-3416 这题的题意就是要找两点之间最短路的路径个数,而且边不能重复. 最大流和最短路的结合.首先正向和反向建图,再跑两遍dijikstra.到这里就求出 ...

  6. ISAP 算法

    Dinic 算法其实已经足够处理大多数的网络流了,但还不够快.接下来介绍的是最优秀的增广路最大流算法:ISAP(Improve Shortest Argumenting Path).它的时间复杂度上界 ...

  7. 网络流系列算法总结(bzoj 3438 1061)

    网络流嘛,怎么看都是一堆逗逼题嘛,反正遇到还是都做不起嘛.... 网络流的模板非常简单,难点都在于建图,网络流的建图解决问题范围之广,下至A+B Problem,上至单纯形,线性规划.所以如果对于网络 ...

  8. 【网络流24题】 No.3 最小路径覆盖问题 (网络流|匈牙利算法 ->最大二分匹配)

    [题意] 给定有向图 G=(V,E).设 P 是 G 的一个简单路(顶点不相交) 的集合.如果 V 中每个顶点恰好在 P 的一条路上,则称 P 是 G 的一个路径覆盖. P 中路径可以从 V 的任何一 ...

  9. ISAP算法

    为什么叫ISAP ISAP(Improved Shortest Augment Path):改进的最短增广路,属于增广路算法 算法 Dinic算法中,我们每次都需要BFS出层次图,而在ISAP中,我们 ...

随机推荐

  1. 【NOIP2014模拟8.25】设备塔

    题目 为了封印辉之环,古代塞姆利亚大陆的人民在异空间中建造了一座设备塔. 简单的说,这座设备塔是一个漂浮在异空间中的圆柱体,圆柱体两头的圆是计算核心,而侧面则是 传输信息所用的数据通道,划分成N *m ...

  2. spark的accumulator值保存在哪里?

    答案:保存在driver端.因此需要对收集的信息的规模要加以控制,不宜过大.避免 driver端的outofmemory问题!!!

  3. Redis :Linux和Window查看版本号

    一.Linux版本:查看服务端版本 **二者都可以** redis-server -v redis-server --version 查看客户端版本 **二者都可以** redis-cli -v re ...

  4. 020:reverse函数补充

    补充reverse两点: 1.如若在反转url时,需要添加参数,那么可以传递 kwargs 参数到 reverse 函数中,实例代码如下: '}) ) 2.如若想添加查询字符串参数,则必须手动进行ur ...

  5. 字典,set

    字典 dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度 存取速度快 key-value存储方式,在放进去的时候,必须根据key算出v ...

  6. c# B/S下 如何优化文件上传速度和实现断点续传问题

    IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag 客户端每次提交下载请求时,服务 ...

  7. UVa 129 Krypton Factor (DFS && 回溯)

    题意 : 如果一个字符串包含两个相邻的重复子串,则称它是“容易的串”,其他串称为“困难的 串”.例如,BB.ABCDACABCAB.ABCDABCD都是容易的串,而D.DC.ABDAB. CBABCB ...

  8. HDU2196computer

    就是求每个点为起始点的最长链的长度. 写一下各个数组的意思吧. f[i][0]为点i向下走最长的距离:f[i][1]为点i向下走第二长的距离: xia[i][0]为点i向下走最长距离所要走的儿子节点: ...

  9. (45)FreeRTOS学习之二

    一:架构概述 FreeRTOS是一个相对较小的应用程序.最小化的FreeRTOS内核仅包括3个(.c)文件和少数头文件,总共不到9000行代码,还包括了注释和空行.一个典型的编译后(二进制)代码映像小 ...

  10. 分布式架构基石-TCP通信协议

    为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样 ...