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
| #include "iostream" #include "algorithm" #include "cstring" #include "cstdio" #include "queue" using namespace std; #define MAXN 1006
class mincmaxf { #define maxn 60003 public: #define N 10006 #define M 100006 #define INF 0x3f3f3f3f int tot, lnk[N], cur[N], ter[M], nxt[M], cap[M], cost[M], dis[N], ret; bool vis[N]; void init( ) { tot = 1; } int add(int u, int v, int w, int c) { ter[++tot] = v, nxt[tot] = lnk[u], lnk[u] = tot, cap[tot] = w, cost[tot] = c; return tot; } int Ade(int u, int v, int w, int c) { add(v, u, 0, -c); return add(u, v, w, c); } bool spfa(int s, int t) { memset(dis, 0x3f, sizeof(dis)); memcpy(cur, lnk, sizeof(lnk)); std::queue<int> q; q.push(s), dis[s] = 0, vis[s] = 1; while (!q.empty()) { int u = q.front(); q.pop(), vis[u] = 0; for (int i = lnk[u]; i; i = nxt[i]) { int v = ter[i]; if (cap[i] && dis[v] > dis[u] + cost[i]) { dis[v] = dis[u] + cost[i]; if (!vis[v]) q.push(v), vis[v] = 1; } } } return dis[t] != INF; } int dfs(int u, int t, int flow) { if (u == t) return flow; vis[u] = 1; int ans = 0; for (int &i = cur[u]; i && ans < flow; i = nxt[i]) { int v = ter[i]; if (!vis[v] && cap[i] && dis[v] == dis[u] + cost[i]) { int x = dfs(v, t, std::min(cap[i], flow - ans)); if (x) ret += x * cost[i], cap[i] -= x, cap[i ^ 1] += x, ans += x; } } vis[u] = 0; return ans; } int mcmf(int s, int t) { int ans = 0; while (spfa(s, t)) { int x; while ((x = dfs(s, t, INF))) ans += x; } return ret; } } F ; int n; int A[MAXN][MAXN] , re[MAXN][MAXN][2]; int s = 10002 , t = 10003; int kk[MAXN][MAXN] , cnt; inline int id( int x , int y ) { return !kk[x][y] ? (kk[x][y] = ++ cnt) : kk[x][y]; } int r[MAXN]; int main() {
cin >> n; cnt = n; F.init(); for( int i = 1 ; i <= n ; ++ i ) for( int j = 1 ; j <= n ; ++ j ) { scanf("%d",&A[i][j]); if( A[i][j] ) F.Ade( s , id( i , j ) , 1 , 0 ); if( A[i][j] == 2 ) { if( i < j ) re[i][j][0] = F.Ade(id(i, j), i, 1, 0), re[i][j][1] = F.Ade(id(i, j), j, 1, 0); } else if( A[i][j] ) F.Ade( id( i , j ) , i , 1 , 0 ); else ++ r[i]; } for( int i = 1 ; i <= n ; ++ i ) { for( int j = 0 ; j < n - r[i] ; ++ j ) F.Ade( i , t , 1 , j ); } cout << ( n * ( n - 1 ) / 2 * ( n - 2 ) / 3 ) - F.mcmf( s , t ) << endl; for( int i = 1 ; i <= n ; ++ i ) { for (int j = 1; j <= n; ++j) { if (A[i][j] != 2) { printf("%d ",A[i][j]); } else { int ki = i , kj = j; if( i > j ) swap( ki , kj ); if( F.cap[re[ki][kj][0]] ) printf("%d ",i>j); else printf("%d ",i<j); } } puts(""); } }
|