码迷,mamicode.com
首页 > 其他好文 > 详细

[luogu2774] [网络流24题] 方格取数问题

时间:2019-02-02 12:44:00      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:continue   ==   else   oid   amp   set   ble   inline   new   

传送门

某个方格如果选了,那么其周边的四个方格都不能选,有点二分图染色的味道。

考虑建立一个二分图。源点向\(x+y\)是奇数的连边,是偶数的向汇点连边。

然后根据最大和 = 全局和 - 舍弃和 = 全局和 - 最大流,求解

可以理解为在这个二分图中存在一个简单割,有一些点就被舍弃掉了,剩下的点就是我们要需选取的。

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 105
#define INF 2147483647

struct edge {
    int v,next,f;
}G[MAXN*MAXN];

int head[MAXN*MAXN],cur[MAXN*MAXN];
int d[MAXN*MAXN];

int N,M,tot = -1;
int S,T,ans = 0;

inline void add(int u,int v,int cap) {
    G[++tot].v = v; G[tot].f = cap; G[tot].next = head[u]; head[u] = tot;
}

inline bool bfs() {

    std::memset(d,0,sizeof(d));
    std::queue <int> q;
    d[S] = 1; q.push(S);

    while(!q.empty()) {
        int u = q.front(); q.pop();
        for(int i=head[u];i!=-1;i=G[i].next) {
            int v = G[i].v;
            if(d[v]||!G[i].f) continue;
            d[v] = d[u] + 1; q.push(v);
        }
    }

    return d[T];
}

int dinic(int u,int a) {
    if(u==T) return a;
    int temp,flow = 0;
    for(int& i=cur[u];i!=-1;i=G[i].next) {
        int v = G[i].v;
        if(d[v]==d[u]+1&&G[i].f) {
            temp = dinic(v,std::min(a,G[i].f));
            flow += temp; a -= temp;
            G[i].f -= temp; G[i^1].f += temp;
            if(!a) return flow;
        }
    }
    return flow;
}

int main() {

    int w;
    scanf("%d%d",&M,&N);
    S = M*N + 1; T = S + 1;
    std::memset(head,-1,sizeof(head));

    for(int i=1;i<=M;++i)
    for(int j=1;j<=N;++j) {
        
        scanf("%d",&w); ans += w; int temp = (i-1)*N+j;
        if((i+j)&1) add(S,temp,w),add(temp,S,0);
        else {
            add(temp,T,w); add(T,temp,0);
            continue;
        }
        if(i>1) add(temp,temp-N,INF),add(temp-N,temp,0);
        if(i<M) add(temp,temp+N,INF),add(temp+N,temp,0);
        if(j>1) add(temp,temp-1,INF),add(temp-1,temp,0);
        if(j<N) add(temp,temp+1,INF),add(temp+1,temp,0);
    
    }

    int maxflow = 0;
    while(bfs()) {
        for(int i=1;i<=T;++i) cur[i] = head[i];
        maxflow += dinic(S,INF);
    }

    printf("%d",ans - maxflow);
    return 0;
}

[luogu2774] [网络流24题] 方格取数问题

标签:continue   ==   else   oid   amp   set   ble   inline   new   

原文地址:https://www.cnblogs.com/Neworld2002/p/10348055.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!