ford-fulkerson
2018年1月29日
13:57
代码如下:
#include <algorithm>
#include <cstring>
#include <string.h>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <utility>
#include <vector>
#include <cstdio>
#include <cmath>
#define LL long long
#define N 40005
using namespace std;
const int maxn = 505;
const int inf = 0x7fffffff;
struct Edge{
int u;
int v;
int c;
int next;
}edge[N];
int cnt;//边数
int head[N];
void addedge(int u,int v,int c)
{
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt].c = c; //正向边初始化为容量
edge[cnt].next = head[u];
head[u] = cnt++;
edge[cnt].u = v;
edge[cnt].v = u;
edge[cnt].c = 0; //反向边容量初始化为0
edge[cnt].next = head[v];
head[v] = cnt++;
}
bool visit[maxn]; // 记录结点i是否已访问
int pre[maxn]; //记录路径
int m, n;
int source, sink; //源点,汇点
bool bfs() //寻找从源点到汇点的增广路,若找到返回true
{
queue<int>q;
memset(pre,-1,sizeof(pre));
memset(visit,false,sizeof(visit));
pre[source] = -1;
visit[source] = true;
q.push(source);
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if(edge[i].c > 0 && !visit[v])
{
pre[v] = i;
visit[v] = true;
if(v == sink){
return true; //存在增广路
}
q.push(v);
}
}
}
return false;
}
int Edmond_Karp()
{
int maxflow = 0;
int delta;
while(bfs()) //反复在源点到汇点间寻找增广路
{
delta = inf;
int i = pre[sink];
while(i != -1)
{
delta = min(delta, edge[i].c); //路径上最小的容量为流量增量
i = pre[edge[i].u];
}
i = pre[sink];
while(i != -1)
{
// 路径上各边容量相应减少,反向边容量相应增加,总流量增加
edge[i].c -= delta; //增广路上的边减去使用的容量
edge[i^1].c += delta; //同时相应的反向边增加残余容量
i = pre[edge[i].u];
}
maxflow +=delta;
}
return maxflow;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int u,v,w;
memset(head,-1,sizeof(head));
for(int i = 0;i < m; i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
source = 1, sink = n;
printf("%d\n", Edmond_Karp());
}
return 0;
}
数据源:
6 9
1 2 16
1 3 13
3 2 4
2 4 12
4 3 9
3 5 14
5 4 7
4 6 20
5 6 4