「网络流 24 题」方格取数

嘛,你把图分类一下

分成横坐标+纵坐标为奇偶...

然后在图上跑一个二分图最大权匹配

然后就是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 }
View Code
原文地址:https://www.cnblogs.com/shatianming/p/12227622.html