#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef pair PII; #define PATH "D:\\QtProjects\\olymp\\" #define forn(i, n) for (int i = 0; i < (n); ++i) const int N = 1000; const int M = 1000000; const int inf = (int)1e9; int head[N], phi[N], dist[N], predArc[N]; int link[M], dest[M], cap[M], cost[M]; int S, T; int arcsCnt = 0; inline void init(){ fill(head, head + N, -1); } inline void add_arc(int from, int to, int ccap, int ccost){ cap[arcsCnt] = ccap; cost[arcsCnt] = ccost; dest[arcsCnt] = to; link[arcsCnt] = head[from]; head[from] = arcsCnt++; } inline void add_edge(int from, int to, int capacity, int cost){ add_arc(from, to, capacity, cost); add_arc(to, from, 0, -cost); } bool used[N]; priority_queue, greater > q; inline int dejkstra(){ /*static int q[N]; int qh = 0, qt = 0; forn (i, N) phi[i] = inf; forn (i, N) used[i] = false; phi[S] = 0; q[qt++] = S; used[S] = true; while (qh != qt) { int u = q[qh++]; qh %= N; used[u] = false; for (int arc = head[u]; arc != -1; arc = link[arc]) { if (cap[arc] == 0) continue; int v = dest[arc]; int d = phi[u] + cost[arc]; if (d < phi[v]) { phi[v] = d; predArc[v] = arc; if (!used[v]) { q[qt++] = v; qt %= N; used[v] = true; } } } } return phi[T]; //forn (i, n) if (phi[i] == INF) phi[i] = 0;*/ fill(used, used + T + 1, false); fill(dist, dist + T + 1, inf); dist[S] = 0; q.emplace(0, S); while (!q.empty()){ // cout << q.size() << endl; int v = q.top().second; q.pop(); if (used[v]) continue; used[v] = true; for (int arc = head[v]; arc != -1; arc = link[arc]){ if (cap[arc] == 0) continue; int u = dest[arc]; int d = dist[v] + (phi[v] - phi[u]) + cost[arc]; if (d < dist[u]){ q.emplace(d, u); dist[u] = d; predArc[u] = arc; } } } return dist[T] + phi[T]; } inline int mcmf(){ int ans = 0; int pushed = 0; while (true){ int ccost = dejkstra(); if (dist[T] == inf) break; int mincap = inf; for (int v = T; v != S; v = dest[predArc[v] ^ 1]){ mincap = min(mincap, cap[predArc[v]]); } for (int v = T; v != S; v = dest[predArc[v] ^ 1]){ cap[predArc[v]] -= mincap; cap[predArc[v] ^ 1] += mincap; } for (int i = 0; i <= T; ++i) if (dist[i] != inf) phi[i] += dist[i]; pushed += mincap; ans += mincap * ccost; } // cout << "pushed = " << pushed << endl; return ans; } int a[300][300]; int sum[301]; int main(){ // freopen(PATH"input.txt", "r", stdin); ios_base::sync_with_stdio(); init(); int n; cin >> n; S = 2 * n; T = S + 1; for (int i = 0; i < n; ++i){ for (int j = 0; j < n; ++j){ cin >> a[i][j]; sum[j] += a[i][j]; } add_edge(S, i, 1, 0); add_edge(n + i, T, 1, 0); } for (int i = 0; i < n; ++i){ for (int j = 0; j < n; ++j){ int cost = sum[i] - a[j][i]; // cout << cost << ' '; add_edge(i, n + j, 1, cost); } // cout << endl; } cout << mcmf() << endl; return 0; }