传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1324
其实题目就是给定n*m棋盘,不能取相邻的格子,最大收益,裸的最小割
Code:
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<climits> #include<queue> using namespace std; const int maxn=20010; struct edge{ int u,v,cap,flow; edge(int _u=0,int _v=0,int _cap=0,int _flow=0): u(_u),v(_v),cap(_cap),flow(_flow){} }; vector<edge>edges; vector<int>G[maxn]; int cur[maxn],vis[maxn]; void add(int u,int v,int cap){ edges.push_back(edge(u,v,cap,0)); G[u].push_back(edges.size()-1); edges.push_back(edge(v,u,0,0)); G[v].push_back(edges.size()-1); } int d[maxn],s,t; bool bfs(){ memset(vis,0,sizeof(vis)); queue<int>q; q.push(s);vis[s]=1; while(!q.empty()){ int u=q.front();q.pop(); for(int i=0;i<G[u].size();i++){ edge e=edges[G[u][i]]; if(e.cap>e.flow&&!vis[e.v]){ d[e.v]=d[u]+1; vis[e.v]=1; q.push(e.v); } } }return vis[t]; } int dfs(int u,int a){ int flow=0,f; if(u==t||!a)return a; for(int &i=cur[u];i<G[u].size();i++){ edge e=edges[G[u][i]]; if(d[e.v]==d[u]+1&&(f=dfs(e.v,min(a,e.cap-e.flow)))>0){ edges[G[u][i]].flow+=f; edges[G[u][i]^1].flow-=f; flow+=f; a-=f; if(!a)break; } }return flow; } int Dinic(){ int flow=0; while(bfs()){ int x=0; do{ flow+=x; memset(cur,0,sizeof(cur)); }while(x=dfs(s,INT_MAX)); }return flow; } int n,tot,m; int hash[201][201]; int a[201][201]; int sum=0; const int dx[4]={0,1,0,-1}; const int dy[4]={1,0,-1,0}; int main(){ cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ cin>>a[i][j]; hash[i][j]=++tot; sum+=a[i][j]; } s=0;t=tot+1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ if((i+j+1)&1) add(s,hash[i][j],a[i][j]); else add(hash[i][j],t,a[i][j]); if((i+j+1)&1) for(int k=0;k<4;k++){ int x=i+dx[k],y=j+dy[k]; if(x<1||x>n||y<1||y>m)continue; add(hash[i][j],hash[x][y],INT_MAX); } } int deb=0; if(deb) for(int i=0;i<edges.size();i++){ edge e=edges[i]; if(i%2==0) printf("%d -> %d cap:%d\n",e.u,e.v,e.cap); } cout<<sum-Dinic()<<endl; return 0; }