SAP + GAP 邻接表:https://blog.csdn.net/Adolphrocs/article/details/84779575
SAP + GAP 邻接矩阵:https://blog.csdn.net/Adolphrocs/article/details/84779661
dinic 邻接表:https://blog.csdn.net/Adolphrocs/article/details/84779691
//�ڽӾ��?��Լ�¼·��
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXN = 107;
const int inf = 1e9 + 7;
int G[MAXN][MAXN], layer[MAXN], G1[MAXN][MAXN];
int P, N;
struct node {
int in[MAXN],
out[MAXN],
Flow;
}a[MAXN];
void InIt() {
memset(G, 0, sizeof G);
memset(G1, 0 ,sizeof G1);
for (int i = 1; i <= P; i++) {
a[1].out[i] = 0;
a[1].in[i] = 0;
a[N + 2].in[i] = 1;
a[N + 2].out[i] = 1;
}
a[1].Flow = inf;
a[N + 2].Flow = inf;
}
bool BFS(int front, int tail) {
int vis[MAXN] = {0};
queue<int> Q;
Q.push(front);
memset(layer, -1, sizeof(layer));
vis[front] = 1;
layer[front] = 0;
while (!Q.empty()){
int u = Q.front();
Q.pop();
if (u == tail) return true;
for (int i = 1; i <= tail; i++){
if (G[u][i] && !vis[i]){
vis[i] = true;
layer[i] = layer[u] + 1;
Q.push(i);
}
}
}
return false;
}
int dfs(int u, int MaxFlow, int tail) {
if (u == tail) return MaxFlow;
int uFlow = 0;
for (int i = 0; i<= tail; i++) {
if (layer[u] + 1 == layer[i] && G[u][i]) {
int flow = min(MaxFlow - uFlow , G[u][i]);
flow = dfs(i, flow, tail);
G[u][i] -= flow;
G[i][u] += flow;
uFlow += flow;
if (uFlow == MaxFlow) break;
}
}
return uFlow ;
}
int dinic(int front, int tail) {
int MaxFlow = 0;
while (BFS(front, tail))
MaxFlow += dfs(front, inf, tail);
return MaxFlow;
}
int main() {
while (scanf("%d", &N ) != EOF) {
int i, j;
InIt();
for (i = 1; i <= N; i++) {
for (j = 1; j <= N; j++)
scanf("%d", G[i][j]);
G1[i][j] = G[i][j];
}
int MaxFlow = dinic(1, N * 2);
//printf("%d\n", MaxFlow);
int k =0, x[MAXN], y[MAXN], flow[MAXN];
for (i = 1; i <= N; i++)
for (j = 1; j <= N ;j++){
if (G[i + N][j] < G1[i + N][j]){
x[k] = i;
y[k] = j;
flow[k++] = G1[i + N][j] - G[i + N][j];
}
}
printf("%d %d\n", MaxFlow, k);
for (i = 0; i < k; i++)
printf("%d %d %d\n", x[i] - 1, y[i] - 1, flow[i]);
}
return 0;
}