您的位置:首页 > 理论基础 > 计算机网络

初识网络流——最大流EK算法

2017-08-20 11:42 323 查看
网络流就是一张有向图,D=(V,E,C),其中V为该图的顶点集,E为有向边,C是弧上的容量,顶点集中包括一个起点和一个终点。

最大流的意思就是从起点出发到终点,在不超过容量的基础上走出一条最大流,比如运送物资,EK算法是比较基础的最大流算法,就是bfs找增广路法,至于增广路是啥我还说不清楚。

最大流入门题

http://poj.org/problem?id=1273

AC代码,虽然我不是很喜欢这个代码(因为不是我自己写的哈哈)

#include<iostream>
using namespace std;
const int msize = 205;
#include<queue>
#include<algorithm>

int n, m;//n条路,m个结点
int r[msize][msize];
int pre[msize];//记录结点i的前向结点
bool vis[msize];//记录结点i是否已经被访问

//用BFS来判断从结点s到t的路径上是否还有delta
bool BFS(int s, int t)
{
queue<int>que;
memset(pre, -1, sizeof(pre));
memset(vis, 0, sizeof(vis));

pre[s] = s;
vis[s] = true;
que.push(s);
int p;
while (!que.empty())
{
p = que.front();
que.pop();
for (int i = 1; i <= m; i++)
{
if (r[p][i] > 0 && !vis[i])
{
pre[i] = p;
vis[i] = true;
if (i == t)//存在增广路经
return true;
que.push(i);
}
}
}
return false;
}

int EK(int s, int t)
{
int maxflow = 0, d;
while (BFS(s, t))
{
d = INT_MAX;
//若有增广路经,就找出最小的delta
for (int i = t; i != s; i = pre[i])
d = min(d, r[pre[i]][i]);
//这是反向边
for (int i = t; i != s; i = pre[i])
{
r[pre[i]][i] -= d;
r[i][pre[i]] += d;
}
maxflow += d;
}
return maxflow;
}

int main()
{
while (cin >> n >> m)
{
memset(r, 0, sizeof(r));
int s, e, c;
for (int i = 0; i < n; i++)
{
cin >> s >> e >> c;
r[s][e] += c;//防止有重边
}
cout << EK(1, m) << endl;
}
return 0;
}


☝我惊喜地发现这个跟hdu上的1532题是一样的,样例都是一样的!

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

关键在于建图

http://poj.org/problem?id=1459

经典题

http://poj.org/problem?id=1149
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: