Problem:
G: イルミネーション
問題
$1 \leq x \leq h , 1 \leq y \leq w$ をみたす格子点 $(x,y)$ に電球がある.
電源装置は座標 $(i+0.5,j+0.5) (1 \leq i < h,1 \leq j < w, i+j$ は偶数）に設置されている(14:21修正).
		座標 $(i+0.5,j+0.5)$ に設置されている電源装置をオンにすると, 座標 $(i,j),(i+1,j),(i,j+1),(i+1,j+1)$ に存在する $4$ つの電球が光る.
$(i,j)$ にある電球がオンになっている電源装置に $1$ つ以上つながっていると, きれいさ $B_{i,j}$ を得られる. あなたは, きれいさの合計分の収入がもらえる.
		また, それぞれの電源装置をオンにすると, $1$ つあたり電気代が $W$ かかる.
いくつかの電源をオンにして「収入の合計 - 電気代の合計」を最大化しなさい.
制約
$2 \leq h, w \leq 50$
$0 \leq B_{i,j},W \leq 10^9$
$h,w$ は偶数
入力はすべて整数
入力形式
入力は以下の形式で与えられる.
$h\ w \ W$
$B_{1,1} \dots B_{1,w}$
$\vdots$
$B_{h,1} \dots B_{h,w}$
出力
「収入の合計 - 電気代の合計」の最大値を出力せよ. また, 末尾に改行も出力せよ.
サンプル
サンプル入力 1
4 4 10
100 100 100 100
100 100 100 100
1 100 100 1
1 1 1 1
サンプル出力 1
970
以下のように $@$ の位置の電源をオンにし, $X$ の位置の電源をオフにするのが最善である.
100 100 100 100
   @       @
100 100 100 100
       @
1   100 100 1
   X       X
1   1   1   1

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#include <stdlib.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
const ll mod=1000000007;
const ll INF=1e15;
#define REP(i,a,b) for(ll i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)
#define pb push_back
struct edge{ ll to; ll cap; ll rev;};
const ll MAXN=2600;
vector<edge> G[MAXN];


const ll Start=2598, Goal=2599;
bool used[MAXN];

void addEdge0(ll from, ll to, ll cap){
    edge A={to,cap,(ll)G[to].size()};
    edge B={from,0,(ll)G[from].size()};
    G[from].push_back(A);
    G[to].push_back(B);
    return;
}//有向グラフを作る

void addEdge1(ll a, ll b, ll cap){
    edge A={b,cap,(ll)G[b].size()};
    edge B={a,cap,(ll)G[a].size()};
    G[a].push_back(A);
    G[b].push_back(B);
    return;
}//無向グラフを作る

ll dfs(ll v, ll t, ll f){
    if(v==t) return f;
    used[v]=true;
    rep(i,G[v].size()){
        edge &e=G[v][i];
        if(!used[e.to] && e.cap>0){
            ll d=dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}



ll MaxFlow(){
    ll ans=0;
    while(true){
        rep(i,MAXN) used[i]=false;
        ll P=dfs(Start,Goal,INF);
        if(P==0) break;
        ans+=P;
    }
    return ans;
}

ll h,w,W;
ll B[51][51];

ll bakkin(ll i,ll j){
    if(h==2 || w==2) return B[i][j]+B[i][j+1]+B[i+1][j]+B[i+1][j+1];
    ll ans=0;
    if(i==0) ans+= B[0][j]+B[0][j+1];
    if(i==h-2) ans+=B[h-1][j]+B[h-1][j+1];
    if(j==0) ans+=B[i][0]+B[i+1][0];
    if(j==w-2) ans+=B[i][w-1]+B[i+1][w-1];
    if(i*(h-2-i)==0 && j*(w-2-j)==0) {
        ll a=i, b=j;
        if(i!=0) a++;
        if(j!=0) b++;
        ans-=B[a][b];
    }
    //cout<<i<<' '<<j<<' '<<ans<<endl;
    return ans;
}

int main(){
    cin>>h>>w>>W;
    ll SUM=0;
    rep(i,h) rep(j,w) cin>>B[i][j];
    rep(i,h) rep(j,w) SUM+=B[i][j];

    rep(i,h-1) rep(j,w-1) if((i+j)%2==0){
        ll K=i*51+j;
        if(i%2==0) {addEdge0(Start,K,W); addEdge0(K,Goal,bakkin(i,j));}
        if(j%2==1) {addEdge0(K,Goal,W); addEdge0(Start,K,0);}
    }

    if(h>2 || w>2){
        for(ll i=1;i<h-1;i+=2){
            for(ll j=1;j<w-1;j+=2){
                ll K=i*51+j;
                addEdge0(K-52,K,B[i][j]);
                addEdge0(K-50,K,B[i][j+1]);
                addEdge0(K+50,K,B[i+1][j]);
                addEdge0(K+52,K,B[i+1][j+1]);
            }
        }
    }

    cout<<SUM-MaxFlow()<<endl;



}
accuracy: 1
time_ms: 20
memory_kb: 3472
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long

struct Dinic {
    struct edge {
        int to, cap, rev;
    };

    int n;
    vector<vector<edge>> G;
    vector<int> level;
    vector<int> iter;

    void bfs(int s) {
        level.assign(n, -1);
        queue<int> que;
        que.push(s);
        level[s] = 0;
        while (que.size()) {
            int v = que.front();
            que.pop();
            for (int i = 0; i < G[v].size(); i++) {
                edge &e = G[v][i];
                if (e.cap > 0 && level[e.to] < 0) {
                    level[e.to] = level[v] + 1;
                    que.push(e.to);
                }
            }
        }
    }

    int dfs(int v, int t, int f) {
        if (v == t) return f;
        for (int i = iter[v]; i < G[v].size(); i++) {
            edge &e = G[v][i];
            if (e.cap > 0 && level[v] < level[e.to]) {
                int d = dfs(e.to, t, min(f, e.cap));
                if (d > 0) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    Dinic(int n) : n(n), G(n), level(n), iter(n) {}

    void add_edge(int from, int to, int cap) {
        G[from].push_back({to, cap, (int) G[to].size()});
        G[to].push_back({from, 0, (int) G[from].size() - 1});
    }

    int max_flow(int s, int t) {
        int flow = 0;
        while (1) {
            bfs(s);
            if (level[t] < 0) return flow;
            iter.assign(n, 0);
            int f;
            while ((f = dfs(s, t, 1e9)) > 0) {
                flow += f;
            }
        }
    }
};

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int h, w, W;
    cin >> h >> w >> W;
    vector<vector<int>> be(h, vector<int>(w));
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            cin >> be[i][j];
        }
    }

    vector<int> as, bs, cs;
    auto push = [&](int a, int b, int c) {
        as.push_back(a);
        bs.push_back(b);
        cs.push_back(c);
    };

    int idx = 0;
    map<pair<int, int>, int> mp;
    constexpr int T = 100000, S = 200000;
    int dy[] = {-1, 1};
    auto get_mid = [&](int i, int j, int d) {
        return be[i][j + d];
    };
    int sum = 0;
    for (int i = 0; i < h - 1; i++) {
        for (int j = 0; j < w - 1; j++) {
            if ((i + j) & 1) continue;
            mp[{i, j}] = idx;
            int B = be[i][j] + be[i + 1][j] + be[i][j + 1] + be[i + 1][j + 1];
            sum += B;
            if (i & 1) {
                push(S, idx, W);
                push(idx, T, B);
            } else {
                push(S, idx, B);
                push(idx, T, W);
            }
            for (int k = 0; k < 2; k++) {
                int x = i - 1;
                int y = j + dy[k];
                if (0 <= x && 0 <= y && y < w - 1) {
//                    cerr << "mp" << endl;
//                    for (auto &p : mp) {
//                        cerr << "(" << p.first.first << "," << p.first.second << ")" << endl;
//                    }
//                    cerr << "cur" << endl;
//                    cerr << "(" << i << "," << j << "), (" << x << "," << y << ")" << endl;
                    assert(mp.count({x, y}));
                    int mid = get_mid(i, j, k);
                    if (x & 1) {
                        push(idx, mp[{x, y}], mid);
                    } else {
                        push(mp[{x, y}], idx, mid);
                    }
                }
            }
            idx++;
        }
    }

    Dinic dinic(idx + 2);
    for (int i = 0; i < as.size(); i++) {
        int a = as[i], b = bs[i], c = cs[i];
        if (a == S) a = idx;
        if (b == T) b = idx + 1;
//        cout << "edge: " << a << ' ' << b << ' ' << c << endl;
        dinic.add_edge(a, b, c);
    }

    cout << sum - dinic.max_flow(idx, idx + 1) << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3492
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

template <typename Edge>
class graph {
    using graph_t = std::vector<std::vector<Edge>>;
public:
    using reference = std::vector<Edge>&;
    using const_reference = std::vector<Edge> const&;
    using iterator = typename graph_t::iterator;
    using const_iterator = typename graph_t::const_iterator;
    using reverse_iterator = typename graph_t::reverse_iterator;

    graph() : g() {}
    graph(int n) : g(n) {}

    reference operator[](int x) { return g[x]; }
    const_reference operator[](int x) const { return g[x]; }

    iterator begin() { return std::begin(g); }
    const_iterator begin() const { return std::begin(g); }
    iterator end() { return std::end(g); }
    const_iterator end() const { return std::end(g); }
    reverse_iterator rbegin() { return std::rbegin(g); }
    reverse_iterator rend() { return std::rend(g); }

    int size() const { return g.size(); }

    void add_node(std::vector<Edge> es) {
        g.push_back(std::move(es));
    }

private:
    std::vector<std::vector<Edge>> g;
};

// ============================================================================
// capacity graph (for maximum flow)
template <typename Capacity>
struct capacity_edge {
    using capacity_type = Capacity;
    int to, rev;
    capacity_type cap;
    capacity_edge(int t, int r, capacity_type c) : to(t), rev(r), cap(c) {}
};

template <typename Capacity>
using capacity_graph = graph<capacity_edge<Capacity>>;

template <typename Capacity>
void add_edge(capacity_graph<Capacity>& g, int from, int to, Capacity cap) {
    g[from].emplace_back(to, static_cast<int>(g[to].size()), cap);
    g[to].emplace_back(from, static_cast<int>(g[from].size() - 1), Capacity{0});
}


template <typename Edge, typename Capacity = typename Edge::capacity_type>
Capacity augment(graph<Edge>& g, std::vector<int> level, std::vector<int>& iter, int v, int t, Capacity f) {
    if(v == t) return f;
    for(int i = iter[v]; i < (int)g[v].size(); ++i) {
        auto& e = g[v][i];
        if(e.cap > 0 && level[v] < level[e.to]) {
            const auto d = augment(g, level, iter, e.to, t, std::min(f, e.cap));
            if(d > 0) {
                e.cap -= d;
                g[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}

template <typename Edge, typename Capacity = typename Edge::capacity_type>
Capacity max_flow(graph<Edge>& g, int s, int t) {
    const auto inf = std::numeric_limits<Capacity>::max() / 2;
    Capacity flow = 0;
    while(true) {
        std::vector<int> level(g.size(), -1);
        level[s] = 0;
        std::queue<int> que;
        que.push(s);
        while(!que.empty()) {
            const int v = que.front();
            que.pop();
            for(auto const& e : g[v]) {
                if(e.cap > 0 && level[e.to] < 0) {
                    level[e.to] = level[v] + 1;
                    que.push(e.to);
                }
            }
        }

        if(level[t] < 0) return flow;
        std::vector<int> iter(g.size());
        Capacity f{0};
        while((f = augment(g, level, iter, s, t, inf)) > 0) {
            flow += f;
        }
    }
}

using ll = long long;

constexpr ll inf = 1e18;

int main() {
    int h, w, W; cin >> h >> w >> W;
    vector<vector<ll>> b(h, vector<ll>(w));
    for(int i = 0; i < h; ++i) {
        for(int j = 0; j < w; ++j) {
            cin >> b[i][j];
        }
    }

    const int source = (h - 1) * (w - 1);
    const int sink = source + 1;
    capacity_graph<ll> g((h - 1) * (w - 1) + 2);
    ll sum = 0;
    for(int i = 0; i < h - 1; ++i) {
        for(int j = 0; j < w - 1; ++j) {
            if((i + j) % 2 != 0) continue;
            const int v = i * (w - 1) + j;
            const ll c = b[i][j] + b[i + 1][j] + b[i][j + 1] + b[i + 1][j + 1];
            sum += c;
            if(i & 1) {
                add_edge(g, source, v, (ll)W);
                add_edge(g, v, sink, (ll)c);
                add_edge(g, (i - 1) * (w - 1) + j - 1, v, (ll)b[i][j]);
                add_edge(g, (i - 1) * (w - 1) + j + 1, v, (ll)b[i][j + 1]);
                if(i + 1 >= h - 1) continue;
                add_edge(g, (i + 1) * (w - 1) + j - 1, v, (ll)b[i + 1][j]);
                add_edge(g, (i + 1) * (w - 1) + j + 1, v, (ll)b[i + 1][j + 1]);
            } else {
                add_edge(g, source, v, (ll)c);
                add_edge(g, v, sink, (ll)W);
            }
            
        }
    }

    cout << sum - max_flow(g, source, sink) << endl;
}
accuracy: 1
time_ms: 170
memory_kb: 3456
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

template <typename Edge>
class graph {
    using graph_t = std::vector<std::vector<Edge>>;
public:
    using reference = std::vector<Edge>&;
    using const_reference = std::vector<Edge> const&;
    using iterator = typename graph_t::iterator;
    using const_iterator = typename graph_t::const_iterator;
    using reverse_iterator = typename graph_t::reverse_iterator;

    graph() : g() {}
    graph(int n) : g(n) {}

    reference operator[](int x) { return g[x]; }
    const_reference operator[](int x) const { return g[x]; }

    iterator begin() { return std::begin(g); }
    const_iterator begin() const { return std::begin(g); }
    iterator end() { return std::end(g); }
    const_iterator end() const { return std::end(g); }
    reverse_iterator rbegin() { return std::rbegin(g); }
    reverse_iterator rend() { return std::rend(g); }

    int size() const { return g.size(); }

    void add_node(std::vector<Edge> es) {
        g.push_back(std::move(es));
    }

private:
    std::vector<std::vector<Edge>> g;
};

// ============================================================================
// capacity graph (for maximum flow)
template <typename Capacity>
struct capacity_edge {
    using capacity_type = Capacity;
    int to, rev;
    capacity_type cap;
    capacity_edge(int t, int r, capacity_type c) : to(t), rev(r), cap(c) {}
};

template <typename Capacity>
using capacity_graph = graph<capacity_edge<Capacity>>;

template <typename Capacity>
void add_edge(capacity_graph<Capacity>& g, int from, int to, Capacity cap) {
    g[from].emplace_back(to, static_cast<int>(g[to].size()), cap);
    g[to].emplace_back(from, static_cast<int>(g[from].size() - 1), Capacity{0});
}


template <typename Edge, typename Capacity = typename Edge::capacity_type>
Capacity augment(graph<Edge>& g, std::vector<int> level, std::vector<int>& iter, int v, int t, Capacity f) {
    if(v == t) return f;
    for(int i = iter[v]; i < (int)g[v].size(); ++i) {
        auto& e = g[v][i];
        if(e.cap > 0 && level[v] < level[e.to]) {
            const auto d = augment(g, level, iter, e.to, t, std::min(f, e.cap));
            if(d > 0) {
                e.cap -= d;
                g[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}

template <typename Edge, typename Capacity = typename Edge::capacity_type>
Capacity max_flow(graph<Edge>& g, int s, int t) {
    const auto inf = std::numeric_limits<Capacity>::max() / 2;
    Capacity flow = 0;
    while(true) {
        std::vector<int> level(g.size(), -1);
        level[s] = 0;
        std::queue<int> que;
        que.push(s);
        while(!que.empty()) {
            const int v = que.front();
            que.pop();
            for(auto const& e : g[v]) {
                if(e.cap > 0 && level[e.to] < 0) {
                    level[e.to] = level[v] + 1;
                    que.push(e.to);
                }
            }
        }

        if(level[t] < 0) return flow;
        std::vector<int> iter(g.size());
        Capacity f{0};
        while((f = augment(g, level, iter, s, t, inf)) > 0) {
            flow += f;
        }
    }
}

using ll = long long;

constexpr ll inf = 1e18;

int main() {
    int h, w, W; cin >> h >> w >> W;
    vector<vector<ll>> b(h, vector<ll>(w));
    for(int i = 0; i < h; ++i) {
        for(int j = 0; j < w; ++j) {
            cin >> b[i][j];
        }
    }

    const int source = (h - 1) * (w - 1);
    const int sink = source + 1;
    capacity_graph<ll> g((h - 1) * (w - 1) + 2);
    int sum = 0;
    for(int i = 0; i < h - 1; ++i) {
        for(int j = 0; j < w - 1; ++j) {
            if((i + j) % 2 != 0) continue;
            const int v = i * (w - 1) + j;
            const ll c = b[i][j] + b[i + 1][j] + b[i][j + 1] + b[i + 1][j + 1];
            sum += c;
            if(i & 1) {
                add_edge(g, source, v, (ll)W);
                add_edge(g, v, sink, (ll)c);
                add_edge(g, (i - 1) * (w - 1) + j - 1, v, (ll)b[i][j]);
                add_edge(g, (i - 1) * (w - 1) + j + 1, v, (ll)b[i][j + 1]);
                if(i + 1 >= h - 1) continue;
                add_edge(g, (i + 1) * (w - 1) + j - 1, v, (ll)b[i + 1][j]);
                add_edge(g, (i + 1) * (w - 1) + j + 1, v, (ll)b[i + 1][j + 1]);
            } else {
                add_edge(g, source, v, (ll)c);
                add_edge(g, v, sink, (ll)W);
            }
            
        }
    }

    cout << sum - max_flow(g, source, sink) << endl;
}
accuracy: 0.1044776119402985
time_ms: 20
memory_kb: 3192
final_rank: 12

code_snippet: #include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
const int INF=1e9,MOD=1e9+7;
const ll LINF=1e18;
using namespace std;
#define int long long
//template
struct Fordfulkerson{
  const int INF = LINF;
  struct edge{
    int to,cap,rev;
    edge(){}
    edge(int to,int cap,int rev):to(to),cap(cap),rev(rev){}
  };

  int n;
  vector<vector<edge> > G;
  vector<int> used;

  Fordfulkerson(){}
  Fordfulkerson(int sz):n(sz),G(n),used(n){}

  void add_edge(int from,int to,int cap){
    G[from].push_back(edge(to,cap,G[to].size()));
    // undirected
    //G[to].push_back(edge(from,cap,G[from].size()-1));
    // directed
    G[to].push_back(edge(from,0,G[from].size()-1));
  }

  int dfs(int v,int t,int f){
    if(v==t) return f;
    used[v]=true;
    for(int i=0;i<(int)G[v].size();i++){
      edge &e = G[v][i];
      if(!used[e.to] && e.cap > 0 ){
        int d=dfs(e.to,t,min(f,e.cap));
        if(d>0){
          e.cap-=d;
          G[e.to][e.rev].cap+=d;
          return d;
        }
      }
    }
    return 0;
  }

  int flow(int s,int t,int lim){
    int fl=0;
    for(;;){
      fill(used.begin(),used.end(),0);
      int f=dfs(s,t,lim);
      if(f==0) return fl;
      fl+=f;
      lim-=f;
    }
  }

  int flow(int s,int t){
    return flow(s,t,INF);
  }

};
int B[60][60];
//main
signed main(){
  int h,w,W;cin>>h>>w>>W;
  for(int i=0;i<h;i++)for(int j=0;j<w;j++)cin>>B[i][j];
  int ans=0;
  Fordfulkerson fl(10000);
  int x[4]={-1,-1,1,1};
  int y[4]={-1,1,-1,1};
  /*
  スイッチはスイッチの左上の電球の場所にあるとする
  左上の角と同じグループのスイッチはOnならSにつける
  もう片方のグループのスイッチはOffならSにつける
  */
  for(int i=0;i<h-1;i+=2){
    for(int j=0;j<w-1;j+=2){
      if(B[i][j]+B[i+1][j]+B[i][j+1]+B[i+1][j+1]<=W)continue;
      ans+=B[i][j]+B[i+1][j]+B[i][j+1]+B[i+1][j+1]-W;
      fl.add_edge(0,100*i+j+1,B[i][j]+B[i+1][j]+B[i][j+1]+B[i+1][j+1]-W);
      for(int k=0;k<4;k++){
        if(i+x[k]<0||i+x[k]>=h-1||j+y[k]<0||j+y[k]>=w-1)continue;
        if(B[i+x[k]][j+y[k]]+B[i+1+x[k]][j+y[k]]+B[i+x[k]][j+1+y[k]]+B[i+1+x[k]][j+1+y[k]]<=W)continue;
        int a=i,b=j;
        if(k==1)b++;
        if(k==2)a++;
        if(k==3){a++;b++;}
        fl.add_edge(100*i+j+1,100*(i+x[k])+j+y[k]+1,B[a][b]);
      }
    }
  }
  for(int i=1;i<h-1;i+=2){
    for(int j=1;j<w-1;j+=2){
      if(B[i][j]+B[i+1][j]+B[i][j+1]+B[i+1][j+1]<=W)continue;
      ans+=B[i][j]+B[i+1][j]+B[i][j+1]+B[i+1][j+1]-W;
      fl.add_edge(100*i+j+1,9999,B[i][j]+B[i+1][j]+B[i][j+1]+B[i+1][j+1]-W);
    }
  }
  cout<<ans-fl.flow(0,9999)<<endl;
}
accuracy: 1
time_ms: 160
memory_kb: 3616
final_rank: 6

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (ll)1000000007 * 1000000007;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef long double ld;
typedef complex<ld> Point;
const ld eps = 1e-2;
const ld pi = acos(-1.0);
typedef pair<ll, ll> LP;
#include<cstring>
struct edge { int to; ll cap;int rev; };
vector<edge> G[100000];
bool used[100000];
void add_edge(int from, int to, ll cap) {
	G[from].push_back(edge{ to, cap, (int)G[to].size() });
	G[to].push_back(edge{ from, 0, (int)G[from].size() - 1 });
}
ll dfs(int v, int t, ll f) {
	if (v == t)return f;
	used[v] = true;
	for (int i = 0; i < (int)G[v].size(); i++) {
		edge &e = G[v][i];
		if (!used[e.to] && e.cap > 0) {
			ll d = dfs(e.to, t, min(f, e.cap));
			if (d > 0) {
				e.cap -= d;
				G[e.to][e.rev].cap += d;
				return d;
			}
		}
	}
	return 0;
}
ll max_flow(int s, int t) {
	ll flow = 0;
	for (;;) {
		memset(used, 0, sizeof(used));
		ll f = dfs(s, t, INF);
		if (f == 0)return flow;
		flow += f;
	}
}

int h, w; ll z;
ll b[50][50];
int main() {
	cin >> h >> w >> z;
	int s = h * w; int t = s + 1;
	rep(i, h) {
		rep(j, w) {
			cin >> b[i][j];
		}
	}
	rep(i, h - 1) {
		rep(j, w - 1) {
			if ((i + j) % 2)continue;
			if (i % 2 == 0) {
				add_edge(s, i*(w-1) + j, z);
			}
			else add_edge(i*(w-1) + j, t, z);
		}
	}
	if (h == 2) {
		ll ans = 0;
		for (int j = 0; j < w - 1; j += 2) {
			ll csum = b[0][j] + b[0][j + 1] + b[1][j] + b[1][j + 1] - z;
			ans += max((ll)0, csum);
		}
		cout << ans << endl;
		return 0;
	}
	if (w == 2) {
		ll ans = 0;
		for (int i = 0; i < h - 1; i += 2) {
			ll csum = b[i][0] + b[i][1] + b[i + 1][0] + b[i + 1][1] - z;
			ans += max((ll)0, csum);
		}
		cout << ans << endl;
		return 0;
	}
	rep(i, h-1) {
		rep(j, w-1) {
			if ((i + j) % 2)continue;
			if (i % 2)continue;
			if (i + 1 < h-1) {
				if (j - 1 >= 0) {
					int to = (i+1) * (w-1) + j - 1;
					add_edge(i*(w-1) + j, to, b[i + 1][j]);
				}
				if (j + 1 < w-1) {
					int to = (i+1) * (w-1) + j + 1;
					add_edge(i*(w-1) + j, to, b[i + 1][j + 1]);
				}
			}
			if(i-1>=0) {
				if (j - 1 >= 0) {
					int to = (i - 1)*(w-1)+ j - 1;
					add_edge(i*(w-1) + j, to, b[i][j]);
				}
				if (j + 1 < w-1) {
					int to = (i - 1)*(w-1) + j + 1;
					add_edge(i*(w-1) + j, to, b[i][j+1]);
				}
			}
		}
	}
	rep(i, h) {
		int ni = 2 * (i / 2); ni *= (w-1);
		add_edge(ni, t, b[i][0]);
		
		ni += w - 2;
		if (w % 2==0) {
			add_edge(ni, t, b[i][w - 1]);
		}
	}
	rep(j, w) {
		if (j == 0 || j == w - 1)continue;
		int ni = 2 * (j / 2);
		add_edge(ni, t, b[0][j]);
		if (h % 2==0) {
			ni += (h - 2)*(w-1);
			add_edge(ni, t, b[h-1][j]);
		}
	}
	ll ans = max_flow(s, t);
	ans = -ans;
	rep(i, h) {
		rep(j, w) {
			ans += b[i][j];
		}
	}
	cout << ans << endl;
	//stop
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 5896
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double Double;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

#define REP(i, n) for(int i=0;i<(int)n;++i)
#define FOR(i, c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()

typedef ll Weight;

struct Edge {
    int src, dst;
    Weight weight;

    Edge(int src, int dst, Weight weight) :
            src(src), dst(dst), weight(weight) {}
};

bool operator<(const Edge &e, const Edge &f) {
    return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
           e.src != f.src ? e.src < f.src : e.dst < f.dst;
}

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

typedef vector<Weight> Array;
typedef vector<Array> Matrix;

const ll INF = 1e18;


#define RESIDUE(s, t) (capacity[s][t]-flow[s][t])

Weight maximumFlow(const Graph &g, int s, int t) {
    int n = g.size();
    Matrix flow(n, Array(n)), capacity(n, Array(n));
    REP(u, n) FOR(e, g[u]) capacity[e->src][e->dst] += e->weight;

    Weight total = 0;
    while (1) {
        queue<int> Q;
        Q.push(s);
        vector<int> prev(n, -1);
        prev[s] = s;
        while (!Q.empty() && prev[t] < 0) {
            int u = Q.front();
            Q.pop();
            FOR(e, g[u]) if (prev[e->dst] < 0 && RESIDUE(u, e->dst) > 0) {
                    prev[e->dst] = u;
                    Q.push(e->dst);
                }
        }
        if (prev[t] < 0) return total; // prev[x] == -1 <=> t-side
        Weight inc = INF;
        for (int j = t; prev[j] != j; j = prev[j])
            inc = min(inc, RESIDUE(prev[j], j));
        for (int j = t; prev[j] != j; j = prev[j])
            flow[prev[j]][j] += inc, flow[j][prev[j]] -= inc;
        total += inc;
    }
}

Graph g;

void add(int a, int b, int f) {
    g[a].push_back(Edge(a, b, f));
    g[b].push_back(Edge(b, a, 0));
}


ll B[55 * 55];


vector<int> E[55 * 55];

int parity[55 * 55];

int main() {
    int h, w;
    ll W;
    cin >> h >> w >> W;

    ll ans = 0;

    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            cin >> B[i * w + j];
            ans += B[i * w + j];
        }
    }

    auto id = [&](int y, int x) {
        return y * w + x;
    };

    g.resize(h * w + 2);
    int ss = g.size() - 1;
    int tt = g.size() - 2;


    int K = 0;
    for (int i = 0; i < h - 1; i++) {
        for (int j = 0; j < w - 1; j++) {
            if ((i + j) % 2) continue;
            for (int k = 0; k < 2; k++) {
                for (int l = 0; l < 2; l++) {
                    if (i + k >= h || j + l >= w) continue;
                    E[id(i + k, j + l)].push_back(K);
                }
            }
            parity[K] = i % 2;
            if (i % 2 == 0) {
                add(ss, K, 0);
                add(K, tt, W);
            } else {
                add(ss, K, W);
                add(K, tt, 0);
            }
            K++;
        }
    }

    for (int k = 0; k < 55 * 55; k++) {
        auto es = E[k];


        if (es.size() == 0) continue;
        if (es.size() == 2) {
            assert(parity[es[0]] != parity[es[1]]);
            if( parity[es[0]] > parity[es[1]] ) swap(es[0], es[1]);
            add(es[1], es[0], B[k]);
        } else {
            assert(es.size() == 1);
            if( parity[es[0]] == 0 ) {
                add(ss, es[0], B[k]);
            }else{
                add(es[0], tt, B[k]);
            }
        }
    }

    cout << ans - maximumFlow(g, ss, tt) << endl;

}
accuracy: 1
time_ms: 60
memory_kb: 101316
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
//#define DEBUG_MODE
#define endl '\n'
#ifdef DEBUG_MODE
#define DEBUG(X) debug_func(X, #X)
#define DEBUG_ENDL endl
#define DEBUG_SEPARATOR_LINE cout<<"=================\n"
#else
#define DEBUG(X) 0
#define DEBUG_ENDL 0
#define DEBUG_SEPARATOR_LINE 0
#endif
#define ALL(V) (V).begin(), (V).end()
#define ALLR(V) (V).rbegin(), (V).rend()
#define DEBUG_ENDL_S(S) ((S).size() ? "\n" : "")
template <typename T> using V = vector<T>;
template <typename T> using VV = V<V<T>>;
template <typename T, typename U> using P = pair<T, U>;
using ll = int64_t;
using PLL = P<ll, ll>;
template <typename T> const T& var_min(const T &t) { return t; }
template <typename T> const T& var_max(const T &t) { return t; }
template <typename Head, typename... Tail> const Head& var_min(const Head &head, const Tail&... tail) { return min(head, var_min(tail...)); }
template <typename Head, typename... Tail> const Head& var_max(const Head &head, const Tail&... tail) { return max(head, var_max(tail...)); }
template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }
template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }
void debug_func_preffix(const string &s) { if(s.size()) cout << s << " = "; }
template <typename T>
void debug_func(const T &t, const string &s = "") {
    debug_func_preffix(s);
    cout << t << DEBUG_ENDL_S(s);
}
template <typename T, typename U>
void debug_func(const P<T, U> &p, const string &s = "") {
    debug_func_preffix(s);
    cout << "(";
    debug_func(p.first);
    cout << ", ";
    debug_func(p.second);
    cout << ")" << DEBUG_ENDL_S(s);
}
template <typename T>
void debug_func(const V<T> &v, const string &s = "") {
    for(ll i = 0; i < v.size(); i++) {
        string t = s + "[" + to_string(i) + "]";
        debug_func(v[i], t);
    }
}

struct Edge{
    ll to, cap, rev_index;
};

class FordFulkerson {
    private:
        vector<vector<Edge>> v;
        ll n;
        bool *used;
        const ll INF = numeric_limits<ll>::max();

        int dfs(ll now, ll goal, ll f){
            if(now == goal) return f;
            used[now] = 1;
            for(Edge &e : v[now]){
                if(used[e.to]){
                    continue;
                }
                if(e.cap <= 0){
                    continue;
                }
                ll d = dfs(e.to, goal, min(f, e.cap));
                if(d > 0){
                    e.cap -= d;
                    v[e.to][e.rev_index].cap += d;
                    return d;
                }
            }
            return 0;
        }

    public:
        FordFulkerson(const vector<vector<pair<ll, ll>>> &v){
            this->n = v.size();
            for(int i = 0; i < n; i++){
                this->v.push_back(vector<Edge>(0));
            }
            for(int i = 0; i < n; i++){
                for(auto e : v[i]){
                    this->v[i].push_back((Edge){e.first, e.second, (ll)this->v[e.first].size()});
                    this->v[e.first].push_back((Edge){i, 0, (ll)this->v[i].size() - 1});
                }
            }
            used = new bool[n];
        }

        ll max_flow(ll start, ll goal){
            ll ret = 0;
            while(1){
                memset(used, 0, n);
                ll add = dfs(start, goal, INF);
                if(add == 0){
                    return ret;
                }
                ret += add;
            }
        }
};

struct Node {
    ll h, w, b;
};

int main() {
    map<PLL, ll> ID;
    ll h, w, W;
    cin >> h >> w >> W;
    VV<ll> B(h, V<ll>(w));
    for(V<ll> &v : B) for(ll &e : v) cin >> e;
    V<Node> odds, evens;
    ll ans = 0;
    for(ll i = 1; i < h; i++) {
        for(ll j = 1; j < w; j++) {
            if((i + j) % 2 == 1) continue;
            ll bsum = 0;
            bsum += B[i - 1][j - 1];
            bsum += B[i - 1][j];
            bsum += B[i][j - 1];
            bsum += B[i][j];
            if(bsum > W) {
                ans += bsum - W;
                DEBUG(PLL(i, j));
                (i & 1 ? odds : evens).push_back(Node{i, j, bsum - W});
                ll tmp = ID.size();
                ID[PLL(i, j)] = tmp + 1;
            }
        }
    }
    ll start = 0, goal = ID.size() + 1;
    VV<PLL> edges(goal + 1);
    for(const auto &e : odds) {
        ll id = ID[PLL(e.h, e.w)];
        edges[start].emplace_back(id, 0);
        edges[id].emplace_back(goal, e.b);
    }
    for(const auto &e : evens) {
        ll id = ID[PLL(e.h, e.w)];
        edges[start].emplace_back(id, e.b);
        edges[id].emplace_back(goal, 0);
    }
    for(const auto &o : odds) {
        for(const auto &e : evens) {
            if(abs(o.h - e.h) == 1 && abs(o.w - e.w) == 1) {
                ll cost = B[min(o.h, e.h)][min(o.w, e.w)];
                ll ido = ID[PLL(o.h, o.w)];
                ll ide = ID[PLL(e.h, e.w)];
                edges[ide].emplace_back(ido, cost);
            }
        }
    }
    cout << ans - FordFulkerson(edges).max_flow(start, goal) << endl;
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3580
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef int _loop_int;
#define REP(i,n) for(_loop_int i=0;i<(_loop_int)(n);++i)
#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a);i<(_loop_int)(b);++i)
#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1;i>=(_loop_int)(a);--i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define CHMIN(a,b) a=min((a),(b))
#define CHMAX(a,b) a=max((a),(b))

const ll INF = 1ll<<60;
// Dinic http://www.prefield.com/algorithm/graph/dinic.html
struct dinic{
  struct edge{int to;ll cost;};
  int n;
  vector< vector<edge> > G;
  vector<vl> flow, capacity;
#define RESIDUE(s,t) (capacity[s][t]-flow[s][t])
  vi level;
  vector<bool> finished;
  dinic(int _n){
    n = _n;
    G.assign(n,vector<edge>());
    flow.assign(n,vl(n,0));
    capacity.assign(n,vl(n,0));
    level.assign(n,0);
    finished.assign(n,false);
  }
  void add_edge(int from,int to,ll cost){
    assert(0<=from && from<n);
    assert(0<=to && to<n);
    G[from].push_back((edge){to,cost});
    G[to].push_back((edge){from,0ll});  // 逆に流すフローのためのダミー辺
  }
  ll dfs(int u, int t, ll cur){
    if(u==t || cur==0) return cur;
    if(finished[u]) return 0;
    finished[u] = true;
    REP(i,G[u].size()){
      edge e = G[u][i];
      if(level[e.to] > level[u]){
        ll f = dfs(e.to, t, min(cur, RESIDUE(u,e.to)));
        if(f>0){
          flow[u][e.to] += f;
          flow[e.to][u] -= f;
          finished[u] = false;
          return f;
        }
      }
    }
    return 0;
  }
  ll calc(int s, int t){
    REP(i,n)REP(j,n)flow[i][j]=capacity[i][j]=0;
    REP(u,n)REP(j,G[u].size()){
      edge e = G[u][j];
      capacity[u][e.to] += e.cost;
    }
    ll total = 0;
    while(true){
      REP(i,n)level[i] = -1;
      level[s] = 0;
      queue<int> Q; Q.push(s);
      int d = n;
      while(!Q.empty()){
        int u = Q.front(); Q.pop();
        REP(i,G[u].size()){
          edge e = G[u][i];
          if(RESIDUE(u,e.to) > 0 && level[e.to] == -1){
            Q.push(e.to);
            level[e.to] = level[u] + 1;
          }
        }
      }
      REP(i,n)finished[i]=false;
      bool flag = false;
      while(true){
        ll f = dfs(s,t,INF);
        if(f==0)break;
        total += f;
        flag = true;
      }
      if(!flag)break;
    }
    return total;
  }
};

int h,w,W;
int b[52][52];

int main(){
  scanf("%d%d%d",&h,&w,&W);
  REP(i,h)REP(j,w)scanf("%d",&b[i][j]);

  map<pii,int> M;
  int it = 0;
  FOR(i,-1,h)FOR(j,-1,w)if((i+j)%2==0){
    M[pii(i,j)] = it++;
  }
  const int S = it++;
  const int T = it++;
  dinic D(it);

  FOR(i,-1,h)FOR(j,-1,w)if((i+j)%2==0){
    int id = M[pii(i,j)];
    bool out = i==-1 || j==-1 || i==h-1 || j==w-1;
    if(i%2==0){
      // on off
      D.add_edge(S,id,out ? INF : (ll)W);
      D.add_edge(id,T,0);
    }else{
      // off on
      D.add_edge(S,id,0);
      D.add_edge(id,T,out ? INF : (ll)W);
    }
  }
  REP(i,h)REP(j,w){
    int lid, rid;
    if(i%2==0 && j%2==0){
      lid = M[pii(i,j)];
      rid = M[pii(i-1,j-1)];
    }else if(i%2==1 && j%2==1){
      lid = M[pii(i-1,j-1)];
      rid = M[pii(i,j)];
    }else if(i%2==0 && j%2==1){
      lid = M[pii(i,j-1)];
      rid = M[pii(i-1,j)];
    }else{
      lid = M[pii(i-1,j)];
      rid = M[pii(i,j-1)];
    }
    D.add_edge(lid,rid,b[i][j]);
  }
  ll ans = 0;
  REP(i,h)REP(j,w)ans += b[i][j];
  ans -= D.calc(S,T);
  printf("%lld\n",ans);
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 29808
final_rank: 5

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (ll)1000000007 * 1000000007;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef long double ld;
typedef complex<ld> Point;
const ld eps = 1e-2;
const ld pi = acos(-1.0);
typedef pair<ll, ll> LP;
#include<cstring>
struct edge { int to; ll cap;int rev; };
vector<edge> G[100000];
bool used[100000];
void add_edge(int from, int to, ll cap) {
	G[from].push_back(edge{ to, cap, (int)G[to].size() });
	G[to].push_back(edge{ from, 0, (int)G[from].size() - 1 });
}
ll dfs(int v, int t, ll f) {
	if (v == t)return f;
	used[v] = true;
	for (int i = 0; i < (int)G[v].size(); i++) {
		edge &e = G[v][i];
		if (!used[e.to] && e.cap > 0) {
			ll d = dfs(e.to, t, min(f, e.cap));
			if (d > 0) {
				e.cap -= d;
				G[e.to][e.rev].cap += d;
				return d;
			}
		}
	}
	return 0;
}
ll max_flow(int s, int t) {
	ll flow = 0;
	for (;;) {
		memset(used, 0, sizeof(used));
		ll f = dfs(s, t, INF);
		if (f == 0)return flow;
		flow += f;
	}
}

int h, w; ll z;
ll b[50][50];
int main() {
	cin >> h >> w >> z;
	int s = h * w; int t = s + 1;
	rep(i, h) {
		rep(j, w) {
			cin >> b[i][j];
		}
	}
	rep(i, h - 1) {
		rep(j, w - 1) {
			if ((i + j) % 2)continue;
			if (i % 2 == 0) {
				add_edge(s, i*(w-1) + j, z);
			}
			else add_edge(i*(w-1) + j, t, z);
		}
	}
	if (h == 2) {
		ll ans = 0;
		for (int j = 0; j < w - 1; j += 2) {
			ll csum = b[0][j] + b[0][j + 1] + b[1][j] + b[1][j + 1] - z;
			ans += max((ll)0, csum);
		}
		cout << ans << endl;
		return 0;
	}
	if (w == 2) {
		ll ans = 0;
		for (int i = 0; i < h - 1; i += 2) {
			ll csum = b[i][0] + b[i][1] + b[i + 1][0] + b[i + 1][1] - z;
			ans += max((ll)0, csum);
		}
		cout << ans << endl;
		return 0;
	}
	rep(i, h-1) {
		rep(j, w-1) {
			if ((i + j) % 2)continue;
			if (i % 2)continue;
			if (i + 1 < h) {
				if (j - 1 >= 0) {
					int to = (i+1) * (w-1) + j - 1;
					add_edge(i*(w-1) + j, to, b[i + 1][j]);
				}
				if (j + 1 < w) {
					int to = (i+1) * (w-1) + j + 1;
					add_edge(i*(w-1) + j, to, b[i + 1][j + 1]);
				}
			}
			if(i-1>=0) {
				if (j - 1 >= 0) {
					int to = (i - 1)*(w-1)+ j - 1;
					add_edge(i*(w-1) + j, to, b[i][j]);
				}
				if (j + 1 < w) {
					int to = (i - 1)*(w-1) + j + 1;
					add_edge(i*(w-1) + j, to, b[i][j+1]);
				}
			}
		}
	}
	rep(i, h) {
		int ni = 2 * (i / 2); ni *= (w-1);
		add_edge(ni, t, b[i][0]);
		
		ni += w - 2;
		if (w % 2==0) {
			add_edge(ni, t, b[i][w - 1]);
		}
	}
	rep(j, w) {
		if (j == 0 || j == w - 1)continue;
		int ni = 2 * (j / 2);
		add_edge(ni, t, b[0][j]);
		if (h % 2==0) {
			ni += (h - 2)*(w-1);
			add_edge(ni, t, b[h-1][j]);
		}
	}
	ll ans = max_flow(s, t);
	ans = -ans;
	rep(i, h) {
		rep(j, w) {
			ans += b[i][j];
		}
	}
	cout << ans << endl;
	//stop
	return 0;
}
accuracy: 0.8656716417910447
time_ms: 50
memory_kb: 5760
final_rank: 10

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (ll)1000000007 * 1000000007;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef long double ld;
typedef complex<ld> Point;
const ld eps = 1e-2;
const ld pi = acos(-1.0);
typedef pair<ll, ll> LP;
#include<cstring>
struct edge { int to; ll cap;int rev; };
vector<edge> G[100000];
bool used[100000];
void add_edge(int from, int to, ll cap) {
	G[from].push_back(edge{ to, cap, (int)G[to].size() });
	G[to].push_back(edge{ from, 0, (int)G[from].size() - 1 });
}
ll dfs(int v, int t, ll f) {
	if (v == t)return f;
	used[v] = true;
	for (int i = 0; i < (int)G[v].size(); i++) {
		edge &e = G[v][i];
		if (!used[e.to] && e.cap > 0) {
			ll d = dfs(e.to, t, min(f, e.cap));
			if (d > 0) {
				e.cap -= d;
				G[e.to][e.rev].cap += d;
				return d;
			}
		}
	}
	return 0;
}
ll max_flow(int s, int t) {
	ll flow = 0;
	for (;;) {
		memset(used, 0, sizeof(used));
		ll f = dfs(s, t, INF);
		if (f == 0)return flow;
		flow += f;
	}
}

int h, w; ll z;
ll b[50][50];
int main() {
	cin >> h >> w >> z;
	int s = h * w; int t = s + 1;
	rep(i, h) {
		rep(j, w) {
			cin >> b[i][j];
		}
	}
	rep(i, h - 1) {
		rep(j, w - 1) {
			if ((i + j) % 2)continue;
			if (i % 2 == 0) {
				add_edge(s, i*(w-1) + j, z);
			}
			else add_edge(i*(w-1) + j, t, z);
		}
	}
	rep(i, h-1) {
		rep(j, w-1) {
			if ((i + j) % 2)continue;
			if (i % 2)continue;
			if (i + 1 < h) {
				if (j - 1 >= 0) {
					int to = (i+1) * (w-1) + j - 1;
					add_edge(i*(w-1) + j, to, b[i + 1][j]);
				}
				if (j + 1 < w) {
					int to = (i+1) * (w-1) + j + 1;
					add_edge(i*(w-1) + j, to, b[i + 1][j + 1]);
				}
			}
			if(i-1>=0) {
				if (j - 1 >= 0) {
					int to = (i - 1)*(w-1)+ j - 1;
					add_edge(i*(w-1) + j, to, b[i][j]);
				}
				if (j + 1 < w) {
					int to = (i - 1)*(w-1) + j + 1;
					add_edge(i*(w-1) + j, to, b[i][j+1]);
				}
			}
		}
	}
	rep(i, h) {
		int ni = 2 * (i / 2); ni *= (w-1);
		add_edge(ni, t, b[i][0]);
		
		ni += w - 2;
		if (w % 2==0) {
			add_edge(ni, t, b[i][w - 1]);
		}
	}
	rep(j, w) {
		if (j == 0 || j == w - 1)continue;
		int ni = 2 * (j / 2);
		add_edge(ni, t, b[0][j]);
		if (h % 2==0) {
			ni += (h - 2)*(w-1);
			add_edge(ni, t, b[h-1][j]);
		}
	}
	ll ans = max_flow(s, t);
	ans = -ans;
	rep(i, h) {
		rep(j, w) {
			ans += b[i][j];
		}
	}
	cout << ans << endl;
	//stop
	return 0;
}
accuracy: 0.8656716417910447
time_ms: 50
memory_kb: 5732
final_rank: 9

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (ll)1000000007 * 1000000007;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef long double ld;
typedef complex<ld> Point;
const ld eps = 1e-2;
const ld pi = acos(-1.0);
typedef pair<ll, ll> LP;
#include<cstring>
struct edge { int to; ll cap;int rev; };
vector<edge> G[100000];
bool used[100000];
void add_edge(int from, int to, ll cap) {
	G[from].push_back(edge{ to, cap, (int)G[to].size() });
	G[to].push_back(edge{ from, 0, (int)G[from].size() - 1 });
}
ll dfs(int v, int t, ll f) {
	if (v == t)return f;
	used[v] = true;
	for (int i = 0; i < (int)G[v].size(); i++) {
		edge &e = G[v][i];
		if (!used[e.to] && e.cap > 0) {
			ll d = dfs(e.to, t, min(f, e.cap));
			if (d > 0) {
				e.cap -= d;
				G[e.to][e.rev].cap += d;
				return d;
			}
		}
	}
	return 0;
}
ll max_flow(int s, int t) {
	ll flow = 0;
	for (;;) {
		memset(used, 0, sizeof(used));
		ll f = dfs(s, t, mod);
		if (f == 0)return flow;
		flow += f;
	}
}

int h, w; ll z;
ll b[50][50];
int main() {
	cin >> h >> w >> z;
	int s = h * w; int t = s + 1;
	rep(i, h) {
		rep(j, w) {
			cin >> b[i][j];
		}
	}
	rep(i, h - 1) {
		rep(j, w - 1) {
			if ((i + j) % 2)continue;
			if (i % 2 == 0) {
				add_edge(s, i*(w-1) + j, z);
			}
			else add_edge(i*(w-1) + j, t, z);
		}
	}
	rep(i, h-1) {
		rep(j, w-1) {
			if ((i + j) % 2)continue;
			if (i % 2)continue;
			if (i + 1 < h) {
				if (j - 1 >= 0) {
					int to = (i+1) * (w-1) + j - 1;
					add_edge(i*(w-1) + j, to, b[i + 1][j]);
				}
				if (j + 1 < w) {
					int to = (i+1) * (w-1) + j + 1;
					add_edge(i*(w-1) + j, to, b[i + 1][j + 1]);
				}
			}
			if(i-1>=0) {
				if (j - 1 >= 0) {
					int to = (i - 1)*(w-1)+ j - 1;
					add_edge(i*(w-1) + j, to, b[i][j]);
				}
				if (j + 1 < w) {
					int to = (i - 1)*(w-1) + j + 1;
					add_edge(i*(w-1) + j, to, b[i][j+1]);
				}
			}
		}
	}
	rep(i, h) {
		int ni = 2 * (i / 2); ni *= (w-1);
		add_edge(ni, t, b[i][0]);
		
		ni += w - 2;
		if (w % 2==0) {
			add_edge(ni, t, b[i][w - 1]);
		}
	}
	rep(j, w) {
		if (j == 0 || j == w - 1)continue;
		int ni = 2 * (j / 2);
		add_edge(ni, t, b[0][j]);
		if (h % 2==0) {
			ni += (h - 2)*(w-1);
			add_edge(ni, t, b[h-1][j]);
		}
	}
	ll ans = max_flow(s, t);
	ans = -ans;
	rep(i, h) {
		rep(j, w) {
			ans += b[i][j];
		}
	}
	cout << ans << endl;
	//stop
	return 0;
}
accuracy: 0.8656716417910447
time_ms: 50
memory_kb: 5760
final_rank: 10