#ifdef NACHIA #define _GLIBCXX_DEBUG #else #define NDEBUG #endif #include #include #include #include using namespace std; using ll = long long; const ll INF = 1ll << 60; #define REP(i,n) for(ll i=0; i using V = vector; template void chmax(A& l, const B& r){ if(l < r) l = r; } template void chmin(A& l, const B& r){ if(r < l) l = r; } #include #include namespace nachia { struct MinimumCostFlow { template using nega_queue = std::priority_queue, std::greater>; using cap = long long; using cost = long long; struct Edge { int to, rev; cap c; cost d; }; int N; int src = 0, snk = 1; std::vector> E; cost fAns = 0; std::vector D, P; std::vector PE; MinimumCostFlow(int n) { N = n; E.resize(n); D.resize(n); PE.resize(n); P.resize(n); } void addEdge(int u, int v, cap cap, cost cost) { E[u].push_back(Edge{ v, (int)E[v].size(), cap, cost }); E[v].push_back(Edge{ u, (int)E[u].size() - 1, 0, -cost }); } void dijkstra() { for(int i=0; i> Q; Q.push({ 0, src }); D[src] = 0; while (Q.size()) { auto d = Q.top().first; int p = Q.top().second; Q.pop(); if (D[p] != d) continue; for (Edge e : E[p]) if (e.c != 0) { auto nxd = d + e.d + P[p] - P[e.to]; if (D[e.to] != -1 && D[e.to] <= nxd) continue; D[e.to] = nxd; PE[e.to] = e.rev; Q.push({ nxd, e.to }); } } for(int i=0; i> N >> M; V> A(N, V(M)); REP(i,N) REP(j,M) cin >> A[i][j]; nachia::MinimumCostFlow mcf(N+M+2); ll off = 1001001001; ll src = N+M, snk = N+M+1; REP(i,N/2){ mcf.addEdge(src, i, 1, 0); REP(j,M) mcf.addEdge(i, N+j, 1, A[i][j]); } REP(i,N/2){ REP(j,M) mcf.addEdge(N+j, N-1-i, 1, off-A[N-1-i][j]); mcf.addEdge(N-1-i, snk, 1, 0); } ll ans = mcf.flow(src, snk, N/2); ans -= off * (N/2); ans = -ans; cout << ans << "\n"; } int main(){ cin.tie(0)->sync_with_stdio(0); testcase(); return 0; }