JZOJ4020. 【雅礼联考DAY02】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

一个数,表示收益的和减去投资的和的最大值。

Sample Input

【样例 1】
2 2
21
12
21
12
【样例 2】
2 2
ZZ
ZZ
11
11
【样例 3】
3 3
XXX
XXX
XXX
aaa
aZa
aaa
【样例 4】
2 4
asam
atik
123A
45BC
【样例 5】
9 8
IIIIIIII
IIWWWWII
IIWIIIII
IIWIIIII
IIWWWWII
IIIIIWII
IIIIIWII
IIWWWWII
IIIIIIII
IIIIIIII
II0000II
II0II0II
II0II0II
II0000II
II0II0II
II0II0II
II0000II
IIIIIIII

Sample Output

【样例 1】4
【样例 2】0
【样例 3】2
【样例 4】71
【样例 5】606

Data Constraint

n,m ≤ 20.

题解

看到n,m很小其实以为是暴力,
实际上不是,是网络流。

先将每个点拆分成两个点,
中间连价值的边。
对整张图进行黑白染色,
S向黑点的连一条cost的边
所以白点向T连一条cost的边,
每个白点向它四路通的黑点连一条正无穷的边。

code

#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h> 
#define ll long long
#define N 100003
#define M 33
#define db double
#define P putchar
#define G getchar
#define inf 998244353
using namespace std;
char ch;
void read(int &n)
{
    n=0;
    ch=G();
    while((ch<'0' || ch>'9') && ch!='-')ch=G();
    ll w=1;
    if(ch=='-')w=-1,ch=G();
    while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
    n*=w;
}

int max(int a,int b){return a>b?a:b;}
//int min(int a,int b){return a<b?a:b;}
ll abs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}

int nxt[N*2],to[N*2],v[N*2],last[N],cur[N],tot;
int q[N],h[N],S,T,ans,n,m,tt,pos,to_;
int val[M][M],cost[M][M];
int fx[4][2]={{1,0},{-1,0},{0,-1},{0,1}},xx,yy;

bool bfs()
{
    int head=0,tail=1;
    for(int i=0;i<=T;i++)h[i]=-1;
    q[0]=S;h[S]=0;
    while(head!=tail)
    {
        int now=q[head];head++;
        for(int i=last[now];i;i=nxt[i])
            if(v[i] && h[to[i]]==-1)
            {
                h[to[i]]=h[now]+1;
                q[tail++]=to[i];
            }
    }
    return h[T]!=-1;
}

int dfs(int x,int f)
{
    if(x==T)return f;
    int w,used=0;
    for(int i=cur[x];i;i=nxt[i])
        if(h[to[i]]==h[x]+1)
        {
            w=f-used;
            w=dfs(to[i],min(w,v[i]));
            v[i]-=w;v[i^1]+=w;
            if(v[i])cur[x]=i;
            used+=w;
            if(used==f)return f;
        }
    if(!used)h[x]=-1;
    return used;
}

void dinic()
{
    while(bfs())
    {
        for(int i=0;i<=T;i++)
            cur[i]=last[i];
        ans-=dfs(S,inf);
    }
}

void ins(int x,int y,int z)
{
    nxt[++tot]=last[x];
    to[tot]=y;
    v[tot]=z;
    last[x]=tot;
}

int V(char ch) 
{
    if('0'<=ch && ch<='9')return ch-'0';
    if('a'<=ch && ch<='z')return ch-'a'+10;
    return ch-'A'+36;
}

int get(int x,int y)
{
    return x*m-m+y;
}

int main()
{
    //freopen("data1.in","r",stdin);
    tot=1;

    read(n);read(m);
    tt=n*m;S=tt*2+1;T=S+1;

    for(int i=1;i<=n;i++)
    {
        for(ch=G();!(('0'<=ch && ch<='9') || ('a'<=ch && ch<='z') || ('A'<=ch && ch<='Z'));ch=G());
        cost[i][1]=V(ch);
        for(int j=2;j<=m;j++)
            ch=G(),cost[i][j]=V(ch);
    }

    for(int i=1;i<=n;i++)
    {
        for(ch=G();!(('0'<=ch && ch<='9') || ('a'<=ch && ch<='z') || ('A'<=ch && ch<='Z'));ch=G());
        val[i][1]=V(ch);
        ans+=val[i][1];
        for(int j=2;j<=m;j++)
            ch=G(),val[i][j]=V(ch),ans+=val[i][j];
    }

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if((i+j)&1)
            {
                pos=get(i,j);
                ins(S,pos,cost[i][j]);
                ins(pos,S,0);

                ins(pos,pos+tt,val[i][j]);
                ins(pos+tt,pos,0);

                for(int k=0;k<4;k++)
                {
                    xx=i+fx[k][0];
                    yy=j+fx[k][1];
                    if(xx>0 && yy>0 && xx<=n && yy<=m)
                    {
                        to_=get(xx,yy);
                        //ins(pos,to_,inf);
                        //ins(to_,pos,inf);

                        ins(pos+tt,to_,inf);
                        ins(to_,pos+tt,0);

                        ins(pos,to_+tt,inf);
                        ins(to_+tt,pos,0);
                    } 
                }
            }
            else
            {
                pos=get(i,j);

                ins(pos,T,cost[i][j]);
                ins(T,pos,0);

                ins(pos,pos+tt,0);
                ins(pos+tt,pos,val[i][j]);
            }

    dinic();
    printf("%d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/lijf2001/article/details/81088359
今日推荐