Mars Exploration question (maximum cost maximum flow)

Mars Exploration question (luogu)

Solution

Easy to think of cost flow

To solve the problem the right point, one is not an obstacle point i split into two points ai, bi

From ai to bi even a flow of positive infinity (represented unlimited pass) at a cost of 0 (expressed through these unproductive) side

If the point is i stones, then again from ai to bi even a flow rate of 1 (represented only once through) at a cost of 1 (this represents earnings through 1) the edge

If the point i can point j and i and j are not obstacles, from the bi aj even to a flow of positive infinity, zero cost side

A1 to flow from even a starting point for detecting the number of vehicles at a cost of 0 edge

From bn to the end of a traffic even as the number of probe vehicles at a cost of 0 edge

Running the largest cost maximum flow

Code

 

#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=3e3,M=1e5;
int pre[N],s,t,car,d[N],n,m,incf[N],a[40][40],inf=1<<30,dis[N];
int head[N],nxt[M],ver[M],edge[M],cost[M],tot=1,maxflow,maxcost;
bool in[N];
int id(int x,int y,int inv)
{
    return (x-1)*m+y+inv*n*m;
}
void add(int u,int v,int w,int c)
{
    ver[++tot]=v,nxt[tot]=head[u],edge[tot]=w,cost[tot]=c,head[u]=tot;
    ver[++tot]=u,nxt[tot]=head[v],edge[tot]=0,cost[tot]=-c,head[v]=tot;
}
bool spfa()
{
    memset(dis,0x80,sizeof(dis));
    memset(pre,0,sizeof(pre));
    int last=dis[s];
    queue <int> q;
    dis[s]=0,q.push(s),incf[s]=1<<30;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        in[u]=false;
        for(int i=head[u],v;i;i=nxt[i])
            if(edge[i]>0 && dis[v=ver[i]]<dis[u]+cost[i])
            {
                dis[v]=dis[u]+cost[i];
                incf[v]=min(edge[i],incf[u]);
                pre[v]=i;
                if(!in[v]) in[v]=true,q.push(v);
            }
    }
    return dis[t]!=last;
}
void update()
{
    maxflow+=incf[t],maxcost+=incf[t]*dis[t];
    int x=t;
    while(x!=s)
    {
        int i=pre[x];
        edge[i]-=incf[t],edge[i^1]+=incf[t];
        x=ver[i^1];
    }
}
void dfs(int x,int y,int pos,int k)
{
    int kx,ky,mov;
    for(int i=head[pos];i;i=nxt[i])
    {
        int v=ver[i];
        if(v==s || v==t || v==pos-n*m || edge[i^1]<=0) continue;
        edge[i^1]--;
        if(v>n*m)
        {
            dfs(x,y,v,k);
            return;
        }
        if(v==(x-1)*m+y+1) kx=x,ky=y+1,mov=1;
        else kx=x+1,ky=y,mov=0;
        printf("%d %d\n",k,mov);
        dfs(kx,ky,v+n*m,k);
        return;
    }
}
int main()
{
    scanf("%d%d%d",&car,&m,&n);
    s=0,t=n*m*2+1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&a[i][j]);
    if(a[n][m]==1 || a[1][1]==1) return 0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(a[i][j]==1) continue;
            add(id(i,j,0),id(i,j,1),inf,0);
            if(a[i][j]==2) add(id(i,j,0),id(i,j,1),1,1);
            if(i<n && a[i+1][j]!=1) add(id(i,j,1),id(i+1,j,0),inf,0);
            if(j<m && a[i][j+1]!=1) add(id(i,j,1),id(i,j+1,0),inf,0);
        }
    add(s,id(1,1,0),car,0),add(id(n,m,1),t,car,0);
    while(spfa()) update();
    for(int i=1;i<=maxflow;i++)
        dfs(1,1,1,i);
    return 0;
}

 

 

 

Guess you like

Origin www.cnblogs.com/hsez-cyx/p/12407511.html