Kaka's Matrix Travels

POJ

Los goo

Given a (n * n \) \ matrix, each cell has a non-negative integer \ (A_ {I, J}, (A_ {I, J} <= 1000) \) , from now \ ((1 1) \) departure, you can turn right or go down, and finally to the \ ((the n-, the n-) \) , each reached a grid, the number taken out of the grid, the grid number becomes \ (0 \) , so that a total walking \ (K \) times, now requires \ (K \) and the maximum number of times achieved squares. \ ((. 1 <= n-<= 50, 0 <= K <= 10 ). \)

Analysis: Construction cost flow model (conversion point side, split point method) each grid \ ((I, J \) ) corresponds to a node \ ((. 1-I) * n-J + \) , split into a point and an out-point, point directed edges, a capacity of 1, the cost of the point to connect two lattice \ ((i, j) \ ) number (expressed through the first point is the number of removed ); another capacity \ (. 1-K \) , cost \ (0 \) . after the (then it passes through the point represented, can no longer access the) \ ((I, J) \) is also a point to \ ((i, j + 1 ) \) and \ ((i + 1, j ) \) in point even directed edges with a capacity of \ (k \) , cost \ (0 \) (how to get there will not have access).

Then \ ((1,1) \) is the source point, \ ((n-, n-) \) is the sink node, the maximum flow can do the most cost.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=200005;//懒得想数组具体要开多大了
int n,k,s,t,max_flow,ans;
int dis[N],visit[N],pre[N],incf[N];
int tot,head[N],nxt[N],to[N],limit[N],w[N];
inline void add(int a,int b,int c,int d){
    nxt[++tot]=head[a];head[a]=tot;
    to[tot]=b;limit[tot]=c;w[tot]=d;
    nxt[++tot]=head[b];head[b]=tot;
    to[tot]=a;limit[tot]=0;w[tot]=-d;
}
inline bool spfa(){
    for(int i=1;i<N;++i)dis[i]=-1e9,visit[i]=0;
    queue<int>q;q.push(s);dis[s]=0;visit[s]=1;
    incf[s]=1<<30;
    while(q.size()){
        int u=q.front();q.pop();visit[u]=0;
        for(int i=head[u];i;i=nxt[i]){
            if(!limit[i])continue;
            int v=to[i];
            if(dis[v]<dis[u]+w[i]){
                dis[v]=dis[u]+w[i];
                incf[v]=min(incf[u],limit[i]);
                pre[v]=i;
                if(!visit[v])visit[v]=1,q.push(v);
            }
        }
    }
    if(dis[t]==-1e9)return false;
    return true;
}
inline void update(){
    int x=t;
    while(x!=s){
        int i=pre[x];
        limit[i]-=incf[t];
        limit[i^1]+=incf[t];
        x=to[i^1];
    }
    max_flow+=incf[t];
    ans+=dis[t]*incf[t];
}
int main(){
    n=read(),k=read();s=1;t=2*n*n;tot=1;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            int val=read();
            add((i-1)*n+j,(i-1)*n+j+n*n,1,val);
            add((i-1)*n+j,(i-1)*n+j+n*n,k-1,0);
            if(j+1<=n)add((i-1)*n+j+n*n,(i-1)*n+j+1,k,0);
            if(i+1<=n)add((i-1)*n+j+n*n,i*n+j,k,0);
        }
    }
    while(spfa())update();
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/PPXppx/p/11614185.html