嘛,你把图分类一下
分成横坐标+纵坐标为奇偶...
然后在图上跑一个二分图最大权匹配
然后就是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