同1565一样,只是数据大了点。
/***************************************** Author :Crazy_AC(JamesQi) Time :2016 File Name : *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; typedef pair<ii,int> iii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int n, m; const int maxn = 51*51; int val[51][51]; int dx[] = {-1, 0, 1, 0}; int dy[] = {0, -1, 0, 1}; int s, t; struct Edge{ int from, to, cap, flow; Edge(){} Edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow){} }; struct ISAP{ int p[maxn], num[maxn], cur[maxn], d[maxn]; int s, t, n, m; bool vis[maxn]; vector<int> G[maxn]; vector<Edge> edges; void init(int n) { this->n = n; for (int i = 0;i <= n;++i) { G[i].clear(); d[i] = INF; } edges.clear(); } void addedge(int from,int to,int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = (int)edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } bool bfs() { memset(vis, false,sizeof vis); queue<int> que; d[t] = 0; vis[t] = true; que.push(t); while(!que.empty()) { int u = que.front(); que.pop(); for (int i = 0;i < G[u].size();++i) { Edge& e = edges[G[u][i]^1]; if (e.cap > e.flow && !vis[e.from]) { vis[e.from] = true; d[e.from] = d[u] + 1; que.push(e.from); } } } return vis[s]; } int Augment() { int u = t, flow = INF; while(u != s) { Edge& e = edges[p[u]]; flow = min(flow, e.cap - e.flow); u = edges[p[u]].from; } u = t; while(u != s) { edges[p[u]].flow += flow; edges[p[u]^1].flow -= flow; u = edges[p[u]].from; } return flow; } int MaxFlow(int s,int t) { this->s = s,this->t = t; int ret = 0; bfs(); if (d[s] >= n) return 0; memset(num, 0,sizeof num); memset(cur, 0,sizeof cur); for (int i = 0;i < n;++i) { if (d[i] < INF) num[d[i]]++; } int u = s; while(d[s] < n) { if (u == t) { ret += Augment(); u = s; } bool ok = false; for (int i = cur[u];i < G[u].size();++i) { Edge& e = edges[G[u][i]]; if (e.cap > e.flow && d[u] == d[e.to] + 1) { ok = true; p[e.to] = G[u][i]; cur[u] = i; u = e.to; break; } } if (!ok) { int Min = n - 1; for (int i = 0;i < G[u].size();++i) { Edge& e = edges[G[u][i]]; if (e.cap > e.flow) Min = min(Min, d[e.to]); } if (--num[d[u]] == 0) break; num[d[u] = Min + 1]++; cur[u] = 0; if (u != s) u = edges[p[u]].from; } } return ret; } }isap; bool vis[51][51]; int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(~scanf("%d%d",&n,&m)) { // cout << "n = " << n << endl; // m = n; int sum = 0; // cout << "m = " << m << endl; for (int i = 1;i <= n;++i) for (int j = 1;j <= m;++j) { scanf("%d",&val[i][j]); sum += val[i][j]; } s = 0,t = n*m + 1; memset(vis, false,sizeof vis); isap.init(t); for (int i = 1;i <= n;++i) { for (int j = 1;j <= m;++j) { if (!vis[i][j]) { int u = (i-1)*m+j; isap.addedge(s, u, val[i][j]); for (int k = 0;k < 4;++k) { int nx = i + dx[k]; int ny = j + dy[k]; if (nx < 1 || nx > n || ny < 1 || ny > m) continue; int v = (nx - 1)*m+ny; if (!vis[nx][ny]) isap.addedge(v, t ,val[nx][ny]); isap.addedge(u, v, INF); vis[nx][ny] = true; // val[nx][ny] = -3; } } } } int ans = sum - isap.MaxFlow(s, t); printf("%d\n", ans); } return 0; }