JZOI 4020 Revolution
Description
地图是个矩形的网格。
可以花费一定金钱在一些格子投资。
被投资的格子或者四连通的格子都被投资的话,我就可以获得该格子的收益。
利益最大化是作为商人的基本准则,但这是计算机的任务,拜托您了。
可以花费一定金钱在一些格子投资。
被投资的格子或者四连通的格子都被投资的话,我就可以获得该格子的收益。
利益最大化是作为商人的基本准则,但这是计算机的任务,拜托您了。
Input
第一行两个数 n,m(n,m ≤ 20),表示矩形的长和宽。
接下来 n 行,每行是 m 个字符组成的字符串,描述投资的花费。
接下来 n 行,每行是 m 个字符组成的字符串,表示该格子的收益。
花费和收益按照一种奇葩的方式给出:
字符 数
‘0’ -’ 9’ 0-9
‘a’ -’ z’ 10-35
‘A’ -’ Z’ 36-61
接下来 n 行,每行是 m 个字符组成的字符串,描述投资的花费。
接下来 n 行,每行是 m 个字符组成的字符串,表示该格子的收益。
花费和收益按照一种奇葩的方式给出:
字符 数
‘0’ -’ 9’ 0-9
‘a’ -’ z’ 10-35
‘A’ -’ Z’ 36-61
Output
一个数,表示收益的和减去投资的和的最大值。
Sol
出门左转BZOJ 3894 文理分科,慢走不送。
#include<bits/stdc++.h> using namespace std; #define p(x,y,z) ((x*m+y)*2+z) struct Maxflow{ #define N 10007 #define M 2000007 #define eho(x) for(int i=head[x];i;i=net[i]) #define Eho(x) for(int& i=hea[x];i;i=net[i]) #define inf (1<<27) int n,tot,fall[M],head[N],hea[N],s,t,cost[M],que[N],be,ed,net[M],gap[N],d[N],x,ret; Maxflow() {tot=1; memset(head,0,sizeof head);} inline void clear(int x,int y){tot=1; memset(head,0,sizeof head);} inline void add(int x,int y,int z){ fall[++tot]=y; net[tot]=head[x]; head[x]=tot; cost[tot]=z; } inline void adds(int x,int y,int z){ add(x,y,z); add(y,x,0); } void init() { memset(gap,0,sizeof gap); memset(d,0,sizeof d); ++gap[d[t]=1]; memcpy(hea,head,sizeof hea); que[be=ed=1]=t; while (be<=ed) { x=que[be++]; eho(x) if (!d[fall[i]]) ++gap[d[fall[i]]=d[x]+1],que[++ed]=fall[i]; } } int get(int x,int fl){ if (x==t) return fl; if (!fl) return 0; int flow=0,tmp; Eho(x) if (d[x]==d[fall[i]]+1&&(tmp=get(fall[i],min(fl,cost[i])))) { flow+=tmp; fl-=tmp; cost[i]-=tmp; cost[i^1]+=tmp; if (!fl) return flow; } if (!(--gap[d[x]])) d[s]=n+1; ++gap[++d[x]],hea[x]=head[x]; return flow; } int isap(int S,int T,int Siz){ s=S; t=T; n=Siz; init(); ret=get(s,inf); while (d[s]<=n) ret+=get(s,inf); return ret; } }G; int S=0,T=1001,n,m,b[89][89],c[89][89]; //const char* p; int chd(char c) { if (c >= '0'&&c <= '9')return c - '0'; if (c >= 'a'&&c <= 'z')return c - 'a' + 10; if (c >= 'A'&&c <= 'Z')return c - 'A' + 36; } int ans,px,py; const int dx[4]={1,-1,0,0},dy[4]={0,0,-1,1}; //class SurroundingGame{ //public: // int maxScore (const vector<string>& p1,const vector<string>& p2) { char p[29]; signed main () { // for (int i=1;) // n=p1.size();m=p1[0].size(); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) { // p=p1[i-1].c_str(); scanf("%s",p); for (int j=1;j<=m;j++) c[i][j]=chd(p[j-1]); } for (int i=1;i<=n;i++) { // p=p2[i-1].c_str(); scanf("%s",p); for (int j=1;j<=m;j++) b[i][j]=chd(p[j-1]),ans+=b[i][j]; } for (int i=1;i<=n;i++) { for (int j=1;j<=m;j++) if ((i+j)&1) { G.adds(S,p(i,j,0),c[i][j]),G.adds(p(i,j,0),p(i,j,1),b[i][j]); for (int o=0;o<4;o++) { px=i+dx[o],py=j+dy[o]; if (px<1||px>n||py<1||py>m) continue; G.adds(p(i,j,0),p(px,py,1),inf), G.adds(p(i,j,1),p(px,py,0),inf); } } else G.adds(p(i,j,1),p(i,j,0),b[i][j]),G.adds(p(i,j,0),T,c[i][j]); } printf("%d\n",ans-G.isap(S,T,T+1)); return 0; }