这是dinic写法,但是数据比较水,EK什么得都能过,据说不拆点也能过
#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 canLink(node n1, node n2) {
for (int i = 1; i <= P; i++){
if (n1.out[i] != n2.in[i] && n2.in[i] != 2) return false;
}
return true;
}
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%d", &P, &N ) != EOF) {
int i, j;
InIt();
for (i = 2; i <= N + 1; i++) {
scanf("%d\n", &a[i].Flow);
for (j = 1; j <= P; j++)
scanf("%d", &a[i].in[j]);
for (j = 1; j <= P; j++)
scanf("%d", &a[i].out[j]);
}
N += 2;
for (i = 1; i <= N; i++)
for (j = 1; j <= N; j++){
if (i == j) {
G1[i][j + N] = G[i][j + N] = a[i].Flow;
}
else if (i != j && canLink(a[i], a[j]) == true) {
G1[i + N][j] = G[i + N][j] = a[i].Flow;
}
}
int MaxFlow = dinic(1, N * 2);
//printf("%d\n", MaxFlow);
int k =0, x[MAXN], y[MAXN], flow[MAXN];
for (i = 2; i < N; i++)
for (j = 2; 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;
}