#include<iostream>
#include<queue>
using std::cin;
using std::queue;
const int size = 201;
int Gf[size][size] = {0};
int pre[size] = {0};
int visited[size] = {0};
int n,m;
int BFS(int src,int des)
{
for(int i = 0;i <= n;i++){visited[i] = 0; pre[i] = 0;}
queue<int>my_queue;
my_queue.push(src);
visited[src] = 1;
int flow = 0x7FFFFFFF;
while(!my_queue.empty())
{
int u = my_queue.front();
my_queue.pop();
for(int i = 1;i <= n;i++)
{
if(i != u && visited[i] == 0 && Gf[u][i] > 0)
{
pre[i] = u;
visited[i] = 1;
my_queue.push(i);
flow = Gf[u][i] > flow ? flow : Gf[u][i];
}
}
}
if(pre[des])
return flow;
return 0;
}
int main(int argc, const char** argv) {
cin>>n>>m;
for(int i = 0; i < m;i++)
{
int x,y,w;
cin>>x>>y>>w;
Gf[x][y] = w;
}
int sum = 0;
int increasement = 0;
while( (increasement = BFS(1,n) ) != 0)
{
int temp = n;
while(temp != 1)
{
int Pi = pre[temp];
Gf[Pi][temp] -= increasement;
Gf[temp][Pi] += increasement;
temp = Pi;
}
sum += increasement;
}
std::cout << "max flow: "<<sum << std::endl;
return 0;
}
一、实验目标
利用Edmonds-Karp算法解决disjoint-paths和edge-connectivity问题
二、实验设计
disjoint-paths
不相交路径的数量在直观上看来就是从src到des完全不同的路径的数量之和
将图中每一个边的容量记为1的话,最大流的值即为disjoint-paths的解
network-connectivity
将每一个边的容量记为1
根据定义,network-connectivity要找的其实就是最小割的值
根据最大流最小割定理,最小割的值就是最大流的值,所以最大流的值就是network-connectivity的解
综上所述,上述两个问题的解答是求最大流的过程
Edmonds-Karp算法
- 图中所有的边的流全部置为0
- 在剩余网络上利用BFS寻找增广路径
- 选取剩余网络中从s到t的路径中最短的一条路径作为增广路径(假设所有边的权重为1)
- 记录增广路径中流值最小边的流值
- 更新剩余网络中的边的流值
- 增加图中最大流的值
cin>>n>>m;
for(int i = 0; i < m;i++)
{
int x,y,w;
cin>>x>>y>>w;
Gf[x][y] = w;
}
int sum = 0;
int increasement = 0;
while( (increasement = BFS(1,n) ) != 0)
{
int temp = n;
while(temp != 1)
{
int Pi = pre[temp];
Gf[Pi][temp] -= increasement;
Gf[temp][Pi] += increasement;
temp = Pi;
}
sum += increasement;
}
BFS_EK
- 与基础的BFS相比,还需记录路径中流值最小边的流值并返回
int BFS(int src,int des)
{
for(int i = 0;i <= n;i++){visited[i] = 0; pre[i] = 0;}
queue<int>my_queue;
my_queue.push(src);
visited[src] = 1;
int flow = 0x7FFFFFFF;
while(!my_queue.empty())
{
int u = my_queue.front();
my_queue.pop();
for(int i = 1;i <= n;i++)
{
if(i != u && visited[i] == 0 && Gf[u][i] > 0)
{
pre[i] = u;
visited[i] = 1;
my_queue.push(i);
flow = Gf[u][i] > flow ? flow : Gf[u][i];
}
}
}
if(pre[des])
return flow;
return 0;
}