序:
在之前的文章中实现了不利用STL实现EK算法,效率也较高。这次我们企图简化代码,减少变量的使用与手写模拟的代码。

注意:vector等STL的container在不开O2优化的时候实现同一个效果普遍比手写要慢。


源代码如下:

/*
About: Max_flow_EK_vector
Auther: kongse_qi
Date:2017/04/22
*/
#include <bits/stdc++.h>
#define INF 0x3f3f3f
#define maxn 20005
#define maxm 200005
#define g_t Get_Int()
#define p_b(x) push_back(x)
#define read(x) g_t, x = in
using namespace std;
/* 部分宏是为了简洁好看 */ struct Edge
{
int from;
int to;
int weight;
Edge(){}
Edge(int f, int t, int w):
from(f), to(t), weight(w){}
};//边表 vector<Edge> edge;//存所有弧的信息
vector<int> arc[maxn];//每个节点相连的弧的编号
typedef vector<int>::iterator iterator_t;//迭代器
int n, m, st, en, max_flow;
iterator_t pre[maxn];//记录上一条弧的编号便于回溯
char *X, *T, *Buffer, c;//读入优化
int in;
bool flag = true; void Get_All()
{
fseek(stdin, 0, SEEK_END);
int file_lenth = ftell(stdin);
Buffer = (char*)malloc(file_lenth);
rewind(stdin);
T = (X = Buffer)+fread(Buffer,1, file_lenth, stdin);
c = *X;
} void Get_Int()
{
in = 0;
while(c < '0' || c > '9') c = *++X;
while(c >= '0' && c <= '9')
{
in = in*10+c-'0';
c = *++X;
}
return ;
} void Init()//当多组数据的时候
{
edge.resize(0);
for(unsigned i = 0; i != n*2; ++i)
{
arc[i].resize(0);
}
max_flow = 0;
return ;
} void Add_Edge(int st, int en, int weight)
{
edge.p_b(Edge(st, en, weight));
edge.p_b(Edge(en, st, 0));//该弧信息与反向弧
arc[st].p_b(edge.size()-2);//编号
arc[en].p_b(edge.size()-1);
return ;
} void Read()
{
int a, b, c;
read(n), read(m);//见宏定义
read(st), read(en);
for(unsigned i = 0; i != m; ++i)
{
read(a), read(b), read(c);
Add_Edge(a, b, c);
}
return ;
} bool Bfs(int st, int en)
{
queue<int> q;
int cur, ne, we;
bool vis[maxn];
memset(vis, 0, sizeof vis);
q.push(st);
vis[st] = true;
while(!q.empty())
{
cur = q.front(), q.pop();
for(iterator_t i = arc[cur].begin(); i != arc[cur].end(); ++i)//迭代器遍历vector
{
ne = edge[*i].to;
we = edge[*i].weight;
if(vis[ne] == false && we > 0)
{
q.push(ne);
pre[ne] = i;//记录当前的弧编号
vis[ne] = true;
pre[ne] = i;
if(ne == en) return true;
}
}
}
return false;
} void EK(int st, int en)
{
int minn;
while(Bfs(st, en))
{
minn = INF;
for(unsigned i = en; i != st; i = edge[*pre[i]].from)
{
minn = min(minn, edge[*pre[i]].weight);
}
for(unsigned i = en; i != st; i = edge[*pre[i]].from)
{
edge[*pre[i]].weight -= minn;
edge[*pre[i]^1].weight += minn;//由于弧和它的反向弧在读入的时候是两两一起的,故可以用异或得到它反向弧的编号
}
max_flow += minn;
}
return ;
} int main()
{
freopen("test.in", "r", stdin); Get_All();
Init();
Read();
EK(st, en);
printf("%d\n", max_flow); return 0;
}

基本意思与非vector实现时是一样的。
效率:非常慢!比非vector实现的要慢1倍,要不是读入优化比较狠肯定要超时。

建议OI比赛的时候不使用STL容器,除非使用例如map等极难手写实现的容器。
不然就等着后面的大数据TLE吧。

箜瑟_qi 2017.04.22 22:14

vector实现最大流EK算法的更多相关文章

  1. 二分图的最大匹配——最大流EK算法

    序: 既然是个图,并且求边数的最大值.那么这就可以转化为网络流的求最大流问题. 只需要将源点与其中一子集的所有节点相连,汇点与另一子集的所有节点相连,将所有弧的流量限制置为1,那么最大流 == 最大匹 ...

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

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

  3. 最大流——EK算法

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

  4. (通俗易懂小白入门)网络流最大流——EK算法

    网络流 网络流是模仿水流解决生活中类似问题的一种方法策略,来看这么一个问题,有一个自来水厂S,它要向目标T提供水量,从S出发有不确定数量和方向的水管,它可能直接到达T或者经过更多的节点的中转,目前确定 ...

  5. POJ-1459(最大流+EK算法)

    Power Network POJ-1459 这题值得思索的就是特殊的输入,如何输入一连串字符.这里采用的方法是根据输入已知的输入格式,事先预定好要接受的数据类型. 这里套用的板子也是最大流的模板,但 ...

  6. 最大流EK算法模板

    最近学了下最大流算法,大概思想算是懵懵懂懂了,现在想把模板记录下来,以备后面深刻学习之用. #include<cstdio> #include<cstring> using n ...

  7. POJ1273 最大流 EK算法

    套了个EK的模板 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdi ...

  8. 【转】最大流EK算法

    转自:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 图-1 如图-1所示,在这个运输网络中,源点S和汇点T分别是1,7 ...

  9. 最大流EK算法

    给定一个有向图G=(V,E),把图中的边看作 管道,每条边上有一个权值,表示该管道 的流量上限.给定源点s和汇点t,现在假设 在s处有一个水源,t处有一个蓄水池,问从 s到t的最大水流量是多少? 网络 ...

随机推荐

  1. linux 根分区扩展

    linux根分区扩容 今天网站上传图片出问题了,一开始还以为是程序问题,后来发现原来是服务器存储空间不够,明明有200G的磁盘空间,没理由这么快就用完,查了一下分区情况,原来有两块磁盘,根分区只挂载在 ...

  2. C#随机取得可用端口号

    TCP与UDP段结构中端口地址都是16比特,可以有在0---65535范围内的端口号.对于这65536个端口号有以下的使用规定: (1)端口号小于256的定义为常用端口,服务器一般都是通过常用端口号来 ...

  3. iOS开发之自定义弹出的键盘

    self.inputField.inputView = myView 按文本框弹出的键盘不再是普通文字输入键盘,而是我们设置的myView.一般把这个方法写在viewDiLoad方法中. 也可以在键盘 ...

  4. iwebshop中的增删改查

    <?php class Text extends IController { public function hello() { $this->redirect('hello'); } p ...

  5. httpclient源码分析之 PoolingHttpClientConnectionManager 获取连接

    PoolingHttpClientConnectionManager是一个HttpClientConnection的连接池,可以为多线程提供并发请求服务.主要作用就是分配连接,回收连接等.同一个rou ...

  6. PMBOK 和 PRINCE2的技术不同的地方是什么

    首先,PMBOK是一个框架指导,PRINCE2是一种实现方法. PMBOK是一种建议及最佳实践的集锦.PMBOK包含项目管理的工具和技术并且是一个指导,告诉我们如何做事情,在一种环境中怎样处理问题;而 ...

  7. zookeeper的安装与部署-集群

    1.Zookeeper的下载与解压     通过后面的链接下载Zookeeper:    Zookeeper下载在此我们下载zookeeper-3.4.5下载后解压至安装目录下,本文我们解压到目录:/ ...

  8. 老李分享:loadrunne动态查询db2数据库

    老李分享:loadrunne动态查询db2数据库   poptest老李认为性能测试脚本开发不仅仅涉及到脚本开发的技术层面,同时也要对一些其他技术有所了解动态链接库的技术,线程安全等等,建议在做下面的 ...

  9. 4.在浏览器中解析XML

    要在浏览器中解析获取XML数据,一般只需经过两个步骤:第一,将XML文档.XML字符串转化成XMLDoc对象.第二,使用JS操作XMLDoc对象. 3.1 将XML文档或XML字符串转化成XMLDoc ...

  10. wireshark filter manualpage

    NAME wireshark-filter - Wireshark filter syntax and reference SYNOPSIS wireshark [other options] [ - ...