嘛,你把图分类一下
分成横坐标+纵坐标为奇偶...
然后在图上跑一个二分图最大权匹配
然后就是max(ans, 全部的-ans)
我代码写得有点...

1 #include<bits/stdc++.h>
2 using namespace std;
3
4 int inf=9999999;
5 int m,n,h[30005],tot=(-1),ans=0,sum=0;
6 int tu[305][305];
7 struct node{
8 int from,to,next,rest;
9 }e[300005];
10
11 int zb(int x,int y){
12 return (x-1)*n+y;
13 }
14
15 void add(int x,int y,int z){
16 tot++;
17 e[tot].next=h[x];
18 h[x]=tot;
19 e[tot].from=x;
20 e[tot].to=y;
21 e[tot].rest=z;
22 }
23
24 int dis[3005],g[3005],flow[3005];
25 bool vis[3005];
26
27 int bfs(int s,int t){
28 queue<int>q;
29 dis[s]=0;
30 q.push(s);vis[s]=true;
31 while(!q.empty()){
32 int u=q.front();vis[u]=false;q.pop();
33 for(int i=h[u];i!=(-1);i=e[i].next){
34 if(dis[e[i].to]>dis[u]+1&&g[e[i].to]==(-1)&&e[i].rest>0){
35 g[e[i].to]=i;
36 flow[e[i].to]=min(flow[u],e[i].rest);
37 dis[e[i].to]=dis[u]+1;
38 if(vis[e[i].to]==false){
39 vis[e[i].to]=true;
40 q.push(e[i].to);
41 }
42 }
43 }
44 }
45 }
46
47 int EK(int s,int t){
48 while(1){
49 memset(vis,false,sizeof(vis));
50 memset(dis,0x7f,sizeof(dis));
51 memset(flow,0x7f,sizeof(flow));
52 memset(g,-1,sizeof(g));
53 bfs(s,t);
54 if(g[t]==(-1))return 0;
55 ans+=flow[t];
56 for(int p=t;p!=(s);p=e[g[p]].from){
57 e[g[p]].rest-=flow[t];
58 e[g[p]^1].rest+=flow[t];
59 }
60
61 }
62 }
63
64 int main(){
65 memset(h,-1,sizeof(h));
66 cin>>m>>n;
67 for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)cin>>tu[i][j];
68 for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){
69 sum+=tu[i][j];
70 if((i+j)%2==0){
71 add(0,zb(i,j),tu[i][j]),add(zb(i,j),0,0);
72 if(i!=1)add(zb(i,j),zb(i-1,j),inf),add(zb(i-1,j),zb(i,j),0);
73 if(j!=1)add(zb(i,j),zb(i,j-1),inf),add(zb(i,j-1),zb(i,j),0);
74 if(i!=m)add(zb(i,j),zb(i+1,j),inf),add(zb(i+1,j),zb(i,j),0);
75 if(j!=n)add(zb(i,j),zb(i,j+1),inf),add(zb(i,j+1),zb(i,j),0);
76 }
77 if((i+j)%2==1)add(zb(i,j),n+m+1,tu[i][j]),add(n+m+1,zb(i,j),0);
78 }
79 EK(0,n+m+1);
80 cout<<max(ans,sum-ans)<<endl;
81 }
来源:https://www.cnblogs.com/shatianming/p/12227622.html
