http://blog.csdn.net/lxy767087094/article/details/68942422
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int dx[]={0,-1,0,1},dy[]={-1,0,1,0}; typedef long long ll; const ll INF=10000000000000000ll; #define MAXN 2505 #define MAXM 30005 int v[MAXM],en,first[MAXN],next[MAXM]; ll cap[MAXM]; int d[MAXN],cur[MAXN]; queue<int>q; int S,T; void Init_Dinic(){memset(first,-1,sizeof(first)); en=0;} void AddEdge(const int &U,const int &V,const ll &W) { v[en]=V; cap[en]=W; next[en]=first[U]; first[U]=en++; v[en]=U; cap[en]=0; next[en]=first[V]; first[V]=en++; } bool bfs() { memset(d,-1,sizeof(d)); q.push(S); d[S]=0; while(!q.empty()) { int U=q.front(); q.pop(); for(int i=first[U];i!=-1;i=next[i]) if(d[v[i]]==-1 && cap[i]) { d[v[i]]=d[U]+1; q.push(v[i]); } } return d[T]!=-1; } ll dfs(int U,ll a) { if(U==T || !a) return a; ll Flow=0,f; for(int &i=cur[U];i!=-1;i=next[i]) if(d[U]+1==d[v[i]] && (f=dfs(v[i],min(a,cap[i])))) { cap[i]-=f; cap[i^1]+=f; Flow+=f; a-=f; if(!a) break; } if(!Flow) d[U]=-1; return Flow; } ll max_flow() { ll Flow=0,tmp=0; while(bfs()) { memcpy(cur,first,sizeof(first)); while(tmp=dfs(S,INF)) Flow+=tmp; } return Flow; } int n,m,pen,A,B,id[55][55]; char a[55][55]; int main(){ scanf("%d%d%d%d",&n,&m,&A,&B); for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ id[i][j]=++pen; } } for(int i=1;i<=n;++i){ scanf("%s",a[i]+1); } S=pen+1; T=S+1; Init_Dinic(); for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ if(a[i][j]=='.'){ AddEdge(S,id[i][j],(ll)B); } else{ AddEdge(id[i][j],T,(ll)B); } } } for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ for(int k=0;k<4;++k){ int tx=i+dx[k],ty=j+dy[k]; if(tx>=1 && tx<=n && ty>=1 && ty<=m){ AddEdge(id[i][j],id[tx][ty],(ll)A); } } } } printf("%lld\n",max_flow()); return 0; }