// 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 文件
//Dinic
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
#define inf 2e9
#define maxN 10005
#define maxM 100005
//#define N 5
/*
int C[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
//const int s = 0;//
//const int t = 4;
int s;
int t;
int N;
int M;
/*
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 } };
*/
int m = 0;
int cnt = 0;
vector<int > W, T;
vector<vector<int>> A(maxN);
void preprocess(vector<vector<int>> C)
{
int ret = 0;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (i != j and C[i][j] < inf)
{
ret++;
int x = i; int y = j; int c = C[i][j];
W.push_back(c);//W即C,C即W也
T.push_back(y);//与cnt对应的
A[x].push_back(cnt);//用于查找x出去的流量
cnt++;
W.push_back(0);
T.push_back(x);//作为反向边也存下来
A[y].push_back(cnt);//用于查找y出去的流量
cnt++;
}
}
}
m = ret;
}
void input()
{
cin>>N;
cin>>M;
cin>>s;
cin>>t;
s=s-1;
t=t-1;
int ret = M;
for (int i = 0; i < M; i++)
{
int x, y;
int c;
cin >> x >> y >> c;
x=x-1;
y=y-1;
W.push_back(c);//W即C,C即W也
T.push_back(y);//与cnt对应的
A[x].push_back(cnt);//用于查找x出去的流量
cnt++;
W.push_back(0);
T.push_back(x);//作为反向边也存下来
A[y].push_back(cnt);//用于查找y出去的流量
cnt++;
}
}
int head = 0, tail = 0;
vector<int > chain(maxM*5, -1);
vector<int> dist(maxN, 0);
bool BFS()
{
head = -1;
tail = -1;
chain[++tail] = s;
fill(dist.begin(),dist.end(),0);
dist[0] = 1;
while (head < tail)
{
int i = chain[++head];
for (int j = 0; j < A[i].size(); j++)
{
int y_cnt = A[i][j];
if (dist[T[y_cnt]]==0 and W[y_cnt])
{
dist[T[y_cnt]] = dist[i] + 1;
chain[++tail] = T[y_cnt];
}
}
}
return dist[t];
}
int find(int cur, int x)
{
if (cur == t) return x;
for (int j = 0; j < A[cur].size(); j++)
{
int y_index = A[cur][j];
if (dist[T[y_index]] == dist[cur] + 1 && W[y_index])
{
int fd = find(T[y_index], min(x, W[y_index]));
if (fd)
{
W[y_index] -= fd;
W[y_index ^ 1] += fd;//y_index一定为偶数,^1就是加1
return fd;
}
}
}
return 0;
}
int main()
{
int f = 0;
input();
while (BFS() != 0) {
f += find(s, inf);
}
cout << f;
return 0;
}