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

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;
}

 

posted @ 2018-07-14 14:36  泪寒之雪  阅读(304)  评论(0编辑  收藏  举报