Luogs P3356 Mars exploration (cost flow), p3356
Description
The Mars exploration team's Landing tank will land on the Mars surface, and there will be multiple obstacle detection vehicles. After the landing of the landing module, the test vehicle will move away from the landing module to the early arrival direction. The rover must also collect rock specimens while moving. Each rock specimen is collected by the rover that first encounters it. Each rock specimen can only be collected once. After the rock specimen is collected, other probes can pass through the original rock specimen. The rover cannot pass through the ground with obstacles. This topic limits that a probe can only move from the login location to the south or east, and multiple probe vehicles can occupy the same position at the same time. If a probe cannot move forward before arriving at the transmitter, all the rock specimens collected by the car will be lost.
A p-Q mesh is used to represent the position between the landing cabin and the transmitter. The landing module is located at (X1, Y1), and is transferred
In (XP, YQ.
X 1, Y 1X2, Y 1X3, Y 1 .. X P-1, Y 1 x p, Y 1
X 1, Y 2X2, Y 2X3, Y 2 .. X P-1, Y 2 x p, Y 2
X 1, Y 3X2, Y 3X3, Y 3 .. X P-1, Y 3 x p, Y 3
......
X 1, Y Q-1 X 2, Y Q-1 X 3, Y Q-1 .. X P-1, Y Q-1 x p, Y Q-1
X 1, y q x 2, y q x 3, y q... X P-1, y q x p, Y Q
The optimal mobile solution of the probe is calculated based on the status of each location, so that the number of probe vehicles reaching the transmitter is the maximum,
In addition, the probes collect the largest number of rock specimens.
Input/Output Format
Input Format:
1st Number of behavior detection vehicles, 2nd behavior P, and 3rd behavior Q. The next Q row is the P-Q grid that represents the position status between the landing class and the transmitter. 3 digits indicate the state of the Mars surface position: 0 indicates flat accessibility, 1 indicates obstacle, and 2 indicates stone.
Output Format:
Each row contains a probe ID and a moving direction. 0 indicates moving south, and 1 indicates moving east.
Input and Output sample input sample #1: Copy
21080 0 0 0 0 0 0 0 0 00 0 0 0 0 1 1 0 0 00 0 0 1 0 2 0 0 0 01 1 0 1 2 0 0 0 0 10 1 0 0 2 0 1 1 0 00 1 0 1 0 0 1 1 0 00 1 2 0 0 0 0 1 0 00 0 0 0 0 0 0 0 0 0
Output example #1: Copy
1 11 11 11 11 01 01 11 11 11 11 01 01 11 01 01 02 12 12 12 12 02 02 02 02 12 02 02 12 02 12 12 1
Description
Number of vehicles, P, Q <= 35
This question is related to deep-sea robots.
But there are also differences
First, this problem is versioning. Therefore, we consider splitting points.
In addition, a solution is required for this question.
We consider the nature of edge discovery: the number of traffic at the reverse side represents the number of times this point has been passed.
Therefore, we can use reverse edges to calculate the number of times the vertex passes.
Then enumerate every car and let it go along.
#include<cstdio>#include<cstring>#include<queue>#include<algorithm>#include<vector>#include<cmath>#define AddEdge(x,y,z,f) add_edge(x,y,z,f),add_edge(y,x,-z,0)using namespace std;const int MAXN=1e5+10;const int INF=1e8+10;inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}int N,M,K,S,T;int anscost=0;struct node{ int u,v,w,f,nxt;}edge[MAXN];int head[MAXN],num=2;inline void add_edge(int x,int y,int z,int f){ edge[num].u=x; edge[num].v=y; edge[num].w=z; edge[num].f=f; edge[num].nxt=head[x]; head[x]=num++;}int Pre[MAXN],vis[MAXN],dis[MAXN];bool SPFA(){ queue<int>q; memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[S]=0; q.push(S); while(q.size()!=0) { int p=q.front();q.pop(); vis[p]=0; for(int i=head[p];i!=-1;i=edge[i].nxt) { if(dis[edge[i].v]>dis[p]+edge[i].w&&edge[i].f) { dis[edge[i].v]=dis[p]+edge[i].w; Pre[edge[i].v]=i; if(!vis[edge[i].v]) vis[edge[i].v]=1,q.push(edge[i].v); } } } return dis[T]<=INF;}void f(){ int nowflow=INF; for(int now=T;now!=S;now=edge[Pre[now]].u) nowflow=min(nowflow,edge[Pre[now]].f); for(int now=T;now!=S;now=edge[Pre[now]].u) edge[Pre[now]].f-=nowflow, edge[Pre[now]^1].f+=nowflow; anscost+=nowflow*dis[T];}void MCMF(){ int ans=0; while(SPFA()) f();}int point=0;int belong[1001][1001],can[1001][1001];main(){ #ifdef WIN32 freopen("a.in","r",stdin); #else #endif memset(head,-1,sizeof(head)); K=read(); M=read();N=read(); for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) belong[i][j]=++point; for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) { int opt=read(); if(opt==2) AddEdge(belong[i][j],belong[i][j]+point,-1,1); if(opt!=1) AddEdge(belong[i][j],belong[i][j]+point,0,INF); if(i<N) AddEdge(belong[i][j]+point,belong[i+1][j],0,INF); if(j<M) AddEdge(belong[i][j]+point,belong[i][j+1],0,INF); } S=0;T=point*4; AddEdge(S,belong[1][1],0,K); AddEdge(belong[N][M]+point,T,0,K); MCMF(); for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) for(int k=head[belong[i][j]];k!=-1;k=edge[k].nxt) if(edge[k].v==belong[i][j]+point) can[i][j]+=edge[k^1].f; for(int kk=1;kk<=K;kk++) { int xx=1,yy=1; while(xx!=N||yy!=M) { if(can[xx+1][yy]) printf("%d 0\n",kk),can[xx][yy]--,xx++; else printf("%d 1\n",kk),can[xx][yy]--,yy++; } } return 0;}