HDU 3820. Golden Eggs

Brief description:

給出一塊 n*m 的區域,已知區域中的每個格子都可以放金蛋或者是銀蛋。
每個格子放金蛋或銀蛋時,可以獲得不同的收益,但如果相鄰的兩個格子放相同的蛋的話,會產生一些代價。(都放金蛋的話產生 g 代價、都放銀蛋的話產生 s 代價)。
求一种放置方案,最大化收益。

http://acm.hdu.edu.cn/showproblem.php?pid=3820

最小割、二分圖。


const int N = int(1e4) + 9, M = int(N*6) * 2;

//struct Network_Flow{

int D[N], hd[N], suc[M], to[M], cap[M];
int n, m, s, t, G, S;

inline void ae(int x, int y, int c){
    suc[m] = hd[x], hd[x] = m, to[m] = y, cap[m++] = c,
    suc[m] = hd[y], hd[y] = m, to[m] = x, cap[m++] = 0;
}

inline void aee(int x, int y, int c){
    suc[m] = hd[x], hd[x] = m, to[m] = y, cap[m++] = c,
    suc[m] = hd[y], hd[y] = m, to[m] = x, cap[m++] = c;
}

#define v to[i]
#define c cap[i]
#define f cap[i^1]

LL sap(){
    LL z=0; static int cnt[N],cur[N],pre[N];
    fill(D,D+n,n),fill(cnt,cnt+n,0);cnt[n]=n;
    int u=s;cur[s]=hd[s];while (D[s]){
#define i cur[u]
        if (u==t){
            int d=INF;for(u=s;u!=t;u=v)checkMin(d,c);
            z+=d;for(u=s;u!=t;u=v)f+=d,c-=d;u=s;
        }
#undef i
        int i;for(i=cur[u];i;i=suc[i]){
            if(D[u]+1==D[v]&&c){cur[u]=i,cur[v]=hd[v],pre[v]=u,u=v;break;}
        }
        if (!i){
            if (!--cnt[D[u]])break;
            D[u]=1;REP_G(i,u)if(c)checkMax(D[u],D[v]);--D[u];
            ++cnt[D[u]];if(u==s)cur[u]=hd[u];else u=pre[u];
        }
    }

    return z;
}

#undef f
#undef c
#undef v


int r, c, tot;

int id(int lv, int i, int j){
    return lv*r*c+i*c+j+1;
}

bool inGrid(int x, int y){
    return x >= 0 && y >= 0 && x < r && y < c;
}

const int NN = 51;
int A[NN][NN], B[NN][NN];

void init(){

    RD(r, c, G, S);

    s = 0, t = 2*r*c+1, n = t+1, m = 2; fill(hd, hd+n, 0); tot = 0;

    REP_2(i, j, r, c) tot += RD(A[i][j]);
    REP_2(i, j, r, c) tot += RD(B[i][j]);

    REP_2(i, j, r, c) ae(id(0,i,j),id(1,i,j),INF);

    REP_2(i, j, r, c) if (i&1^j&1){
        ae(s, id(0,i,j), A[i][j]), ae(id(1,i,j), t, B[i][j]);
        REP(d, 4){
            int x = i + dx[d], y = j + dy[d];
            if (inGrid(x, y)) ae(id(0,i,j),id(1,x,y),G);
        }
    }
    else{
        ae(s, id(0,i,j), B[i][j]), ae(id(1,i,j), t, A[i][j]);
        REP(d, 4){
            int x = i + dx[d], y = j + dy[d];
            if (inGrid(x, y)) ae(id(0,i,j),id(1,x,y),S);
        }
    }
}

//} G;



int main(){

#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif

    Rush{
        init();
        OT(tot - sap());
    }
}