1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#include <cassert>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define mkp make_pair
#define fi first
#define se second
using namespace std;
const int _ = 2e4 + 7;
const int __ = 1e5 + 7;
const int inf = 1e9;
const int S = 2e4 + 1, T = 2e4 + 2;
int n, ind[_], a[107][107], cnt, ans;
int dis[_], dep[_], lst[_], cur[_], nxt[__], to[__], cap[__], wgt[__], tot = 1;
bool b[_];
queue<int> q;
pair<int, int> e[_];
void Add(int x, int y, int c, int w) {
nxt[++tot] = lst[x], to[tot] = y, cap[tot] = c, wgt[tot] = w, lst[x] = tot;
nxt[++tot] = lst[y], to[tot] = x, cap[tot] = 0, wgt[tot] = -w, lst[y] = tot;
}
int C2(int n) { return n ? 1ll * n * (n - 1) / 2 : 0; }
bool SPFA() {
memset(dis, 0x3f, sizeof dis);
memset(dep, 0, sizeof dep);
dis[S] = 0, dep[S] = 1, q.push(S);
while (!q.empty()) {
int u = q.front(); q.pop(); b[u] = 0;
for (int i = lst[u]; i; i = nxt[i]) {
int v = to[i];
if (dis[v] <= dis[u] + wgt[i] or !cap[i]) continue;
dis[v] = dis[u] + wgt[i], dep[v] = dep[u] + 1;
if (!b[v]) q.push(v), b[v] = 1;
}
}
return dis[T] != dis[0];
}
int Extend(int u, int flow) {
if (u == T) return flow;
int res = flow;
for (int &i = cur[u]; i; i = nxt[i]) {
int v = to[i];
if (dis[v] != dis[u] + wgt[i] or dep[v] != dep[u] + 1 or !cap[i]) continue;
int cst = Extend(v, min(cap[i], res));
cap[i] -= cst, cap[i ^ 1] += cst, res -= cst;
if (!res) break;
}
return flow - res;
}
void Dinic() {
int flow;
while (SPFA()) {
memcpy(cur, lst, sizeof lst);
do {
flow = Extend(S, inf);
ans -= dis[T] * flow;
} while (flow);
}
}
int main() {
cin >> n; ans = 1ll * n * (n - 1) * (n - 2) / 6;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j) scanf("%d", &a[i][j]);
for (int i = 1; i <= n; ++i)
for (int j = i + 1; j <= n; ++j)
if (a[i][j] == 0) ++ind[i];
else if (a[i][j] == 1) ++ind[j];
else {
e[++cnt] = mkp(i, j);
Add(S, cnt + n, 1, 0);
Add(cnt + n, i, 1, 0);
Add(cnt + n, j, 1, 0);
}
for (int i = 1; i <= n; ++i) {
ans -= C2(ind[i]);
for (int j = ind[i] + 1; j < n; ++j) Add(i, T, 1, C2(j) - C2(j - 1));
}
Dinic();
cout << (n < 3 ? 0 : ans) << endl;
for (int u = 1; u <= cnt; ++u)
for (int i = lst[n + u]; i; i = nxt[i]) {
int v = to[i];
if (v == e[u].fi and !cap[i]) { a[e[u].fi][e[u].se] = 0; break; }
if (v == e[u].se and !cap[i]) { a[e[u].fi][e[u].se] = 1; break; }
}
for (int i = 1; i <= n; ++i)
for (int j = 1; j < i; ++j) a[i][j] = 1 - a[j][i];
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) printf("%d ", a[i][j]);
putchar('\n');
}
return 0;
}
|