// algorithm_FF.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include <set>
#include <math.h>
#include <algorithm>
//Max stream FF算法
//Matrix representation
#define inf INT_MAX
//#define N 5
int D[5][5] = { {0,4,6,inf,inf},
{inf,0,2,3,inf},
{inf,inf,0,inf,4},
{inf, inf, inf, 0, 5},
{inf,inf,inf,inf,0} };
#define N 6
int C[6][6] = { {0,8,12,inf,inf,inf},
{inf,0,inf,6,10,inf},
{inf,2,0,10,inf,inf},
{inf, inf, inf,0, inf, 8},
{inf,inf,inf,2,0,10},
{inf,inf,inf,inf,inf,0 } };
struct Edge {
int c;
int f;
};
Edge edge[N][N];
int flag[N];//各点是否被标记
int prev[N];//前面一个节点是谁
int delta[N];//到j未止的最小值min(min(all(c-f)),min(f_))
int chain[N];//
void init_edge(int mat[][N])//第二维开始要标记
{
for (int i = 0; i < N;i++)
{
for (int j = 0; j < N; j++)
{
if (mat[i][j] != 0 and mat[i][j] < inf)
{
edge[i][j].c = mat[i][j];
edge[i][j].f = 0;
}
}
}
}
const int s = 0;//为什么被改了
const int t = 5;
//using namespace std;
void FF()
{
while (1)
{
memset(flag, 0xff, sizeof(flag));//置为-1//表示是否标号.-1为标号,0为已标号未检查,1为标号已检查
memset(prev, 0xff, sizeof(prev));//置为-1//
memset(delta, 0xff, sizeof(delta));//置为-1
flag[s] = 0;//
prev[s] = 0;
delta[s] = inf;
int edge_head = -1;//Delta,书中大写三角形
int edge_tail = 0;
chain[edge_tail] = s;
while (edge_head < edge_tail)//第一次为0<1;1,3//BFS搜索
{
edge_head++;//第一次为1
int i;
i = chain[edge_head];//第一次为s,0,1,1//2,2//3,3//4,4//5,5.。/4,3节点//
for (int j = 1; j < N; j++)
{
if (flag[j] == -1)//未被标记者
{
if (edge[i][j].c < inf and edge[i][j].f < edge[i][j].c)//邻接且不饱和
{
flag[j] = 0;
prev[j] = i;
delta[j] = std::min(delta[i], edge[i][j].c - edge[i][j].f);
chain[++edge_tail] = j;//第一次为edge_tail=2,chain[2]=1;//二:3,2//内存泄露了这里改进了
}
else if (edge[j][i].c < inf and edge[j][i].f>0)//
{
flag[j] = 0;
prev[j] = -i;
delta[j] = std::min(delta[i], edge[j][i].f);
chain[++edge_tail] = j;//
}
}
}
flag[i] = 1;//表示已经处理????不知道
}
if (delta[t] == 0 or flag[t] == -1)//delta[t]=0表示,找不到增广链了出发不了即发点饱和了,flag[t]=-1表示中断了,到不了t了,即不存在增广路径了flag中没有了(已标号未检查)
break;//结束了
int k1 = t;
int k0 = abs(prev[k1]);
int a = delta[t];
while (1)//回溯
{
if (edge[k0][k1].c < inf)
edge[k0][k1].f += a;
else if (edge[k1][k0].c < inf)
edge[k1][k0].f -= a;
if (k0 == s)
break;
k1 = k0;
k0 = abs(prev[k1]);
}
delta[t] = 0;//新一轮开始
}
int f = 0;
for (int j = 1; j < N; j++)
{
if (edge[s][j].f < inf)
{
f += edge[s][j].f;
}
}
std::cout << "maxflow" << f << std::endl;
}
int main()
{
int f = 0;
init_edge(C);
FF();
std::cout << "Hello World!\n";
}
/*
#include<vector>
#include <algorithm>
#define maxn 1200
#define INF 2e9
using namespace std;
int i, j, k, n, m, h, t, tot, ans, st, en;
struct node {
int c, f;
}edge[maxn][maxn];
int flag[maxn], pre[maxn], alpha[maxn], q[maxn], v;
int read() {
char c; int x; while (c = getchar(), c<'0' || c>'9'); x = c - '0';
while (c = getchar(), c >= '0'&&c <= '9') x = x * 10 + c - '0'; return x;
}
//两个例子1// 6 9 1 6 1 2 8 1 3 12 2 4 6 2 5 10 3 2 2 3 4 10 4 6 8 5 4 2 5 6 10
//2//5 6 1 5 1 2 4 1 3 6 2 3 2 2 4 3 3 5 4 4 5 5
void bfs() {
memset(flag, 0xff, sizeof(flag)); memset(pre, 0xff, sizeof(pre)); memset(alpha, 0xff, sizeof(alpha));
flag[st] = 0; pre[st] = 0; alpha[st] = INF; h = 0, t = 1; q[t] = st;
while (h < t) {
h++; v = q[h];
for (int i = 1; i <= n; i++) {
if (flag[i] == -1) {
if (edge[v][i].c < INF&&edge[v][i].f < edge[v][i].c) {
flag[i] = 0; pre[i] = v; alpha[i] = min(alpha[v], edge[v][i].c - edge[v][i].f); q[++t] = i;
}
else if (edge[i][v].c < INF&&edge[i][v].f>0) {
flag[i] = 0; pre[i] = -v; alpha[i] = min(alpha[v], edge[i][v].f); q[++t] = i;
}
}
}
flag[v] = 1;
}
}
void Ford_Fulkerson() {
while (1) {
bfs();
if (alpha[en] == 0 || flag[en] == -1) {
break;
}
int k1 = en, k2 = abs(pre[k1]); int a = alpha[en];
while (1) {
if (edge[k2][k1].c < INF) edge[k2][k1].f += a;
else if (edge[k1][k2].c < INF) edge[k1][k2].f -= a;
if (k2 == st) break;
k1 = k2; k2 = abs(pre[k1]);
}
alpha[en] = 0;
}
}
void flow() {
int maxflow = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
if (i == st && edge[i][j].f < INF) maxflow += edge[i][j].f;
}
printf("%d", maxflow);
}
int main() {
int u, v, c, f;
n = read(); m = read(); st = read(); en = read();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) edge[i][j].c = INF, edge[i][j].f = 0;
for (int i = 1; i <= m; i++) {
u = read(); v = read(); c = read();
edge[u][v].c = c;
}
Ford_Fulkerson();
flow();
return 0;
}
*/
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门提示:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
来源:https://www.cnblogs.com/Jonn-Liu/p/11511707.html