您的位置:首页 > 其它

洛谷P1126-机器人搬重物-BFS/SPFA

2017-08-11 22:56 260 查看

洛谷P1126-机器人搬重物-BFS/SPFA

Description

机器人移动学会(RMI)现在正尝试用机器人搬运物品。机器人的形状是一个直径1.6米的球。在试验阶段,机器人被用于在一个储藏室中搬运货物。储藏室是一个N*M的网格,有些格子为不可移动的障碍。机器人的中心总是在格点上,当然,机器人必须在最短的时间内把物品搬运到指定的地方。机器人接受的指令有:向前移动1步(Creep);向前移动2步(Walk);向前移动3步(Run);向左转(Left);向右转(Right)。每个指令所需要的时间为1秒。请你计算一下机器人完成任务所需的最少时间。

Input

输入的第一行为两个正整数N,M(N,M<=50),下面N行是储藏室的构造,0表示无障碍,1表示有障碍,数字之间用一个空格隔开。接着一行有四个整数和一个大写字母,分别为起始点和目标点左上角网格的行与列,起始时的面对方向(东E,南S,西W,北N),数与数,数与字母之间均用一个空格隔开。终点的面向方向是任意的。

Output

一个整数,表示机器人完成任务所需的最少时间。如果无法到达,输出-1。

Sample Input

9 10
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0
7 2 2 7 S


Sample Output

12


Hint



思路

很明显可以用BFS来解决,不过今天是最短路专题,选这个就是因为其实很大一部分的BFS都可以转化为SPFA来解决,借用大佬的讲解说一下建图思路

很显然,这个题目是一个搜索,我们可以用i,j,k来唯一标识它的状态,i表示行,j表示列,k表示方向(自己定义即可),对于每一个状态,有5种转移方式(左转,右转,前1,前2,前3),而这5种转移是等价的(均耗费时间1),因此可以很好的用广度优先搜索来解决(广搜是基于路径相等的一种搜索,在这里它搜索的不再是点,而是加上方向共同表示的状态),由于边权均为1 ,所以先搜到的状态一定是时间最少的,它不用再入队列。而对于不等价的情况(转移时时间不都是1),或是有其他转换的更复杂的情况,搜索是无法解决的,这里主要讲一下图的构建。

一个状态可以向左转,向右转,进1,2,3,所以把每个状态与其可转移的状态连接,边权赋为所需时间,

每一个状态即为图中的点,为了处理简便,我们用一个单独的数代表i,j,k,这里可以用放缩,即定义

s=x*i+y*j+k,做到可以唯一标识每一个状态; 特别注意,这是一个有向图,你不能倒着走 时间复杂度:50*50*4 共10000个状态,每个点最多5条边,边数为50000,SPFA可以承受!

注意初始化,不能达到的点不再处理!

AC代码

#include <iostream>
#include <queue>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <string>
#define LL long long
#define ULL unsigned long long
#define mem(a,n) memset(a,n,sizeof(a))
#define fread freopen("in.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
#define N 1010
#define INF 0x3f3f3f3f
#define eps 1e-9
using namespace std;
const int xx[4]={-1,0,1,0};
const int yy[4]={0,1,0,-1};
struct Con{
int x,y,dir;
Con(int a,int b,int c):x(a),y(b),dir(c){}
};
struct Edge{
Con from,to;
int dist;
Edge(Con u,Con v,int d):from(u),to(v),dist(d){};
};
struct SPFA{
vector<Edge> edges;
vector<int> G[110][110][4];
bool mp[110][110];
bool inque[110][110][4];
int d[110][110][4];
int cnt[110][110][4];
int n,m;

bool valid(int x,int y){
return x>0&&y>0&&x<n&&y<m&&!mp[x][y];
}

void init(int n,int m){
this->n=n;
this->m=m;
int temp;
mem(mp,0);
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
scanf("%d",&temp);
if(temp){
mp[i][j]=mp[i+1][j]=mp[i][j+1]=mp[i+1][j+1]=true;
}
}
}
for(int i=0;i<55;++i){
for(int j=0;j<55;++j){
for(int k=0;k<4;++k){
G[i][j][k].clear();
}
}
}
bool canwalk;
edges.clear();
for(int i=1;i<n;++i){
for(int j=1;j<m;++j){
if(!mp[i][j]){
for(int k=0;k<4;++k){
this->AddEdge(Con(i,j,k),Con(i,j,(k+1)%4),1);
this->AddEdge(Con(i,j,k),Con(i,j,(k+3)%4),1);
canwalk=true;
for(int len=1;canwalk&&len<4;++len){
if(valid(i+yy[k]*len,j+xx[k]*len)){
this->AddEdge(Con(i,j,k),Con(i+yy[k]*len,j+xx[k]*len,k),1);
}else{
canwalk=false;
}
}
}
}
}
}
}

void AddEdge(Con from,Con to,int dist){
edges.push_back(Edge(from,to,dist));
m=edges.size();
G[from.x][from.y][from.dir].push_back(m-1);
}

bool spfa(Con s){
queue<Con> que;
memset(inque,0,sizeof(inque));
memset(cnt,0,sizeof(cnt));
memset(d,INF,sizeof(d));
que.push(s);
d[s.x][s.y][s.dir]=0;
while(!que.empty()){
Con temp=que.front();
if(cnt[temp.x][temp.y][temp.dir]==n){
return true;
}
que.pop();
inque[temp.x][temp.y][temp.dir]=false;
for(int i=0;i<G[temp.x][temp.y][temp.dir].size();++i){
Edge &e=edges[G[temp.x][temp.y][temp.dir][i]];
if(d[e.to.x][e.to.y][e.to.dir]>d[temp.x][temp.y][temp.dir]+e.dist){
d[e.to.x][e.to.y][e.to.dir]=d[temp.x][temp.y][temp.dir]+e.dist;

9f43
if(!inque[e.to.x][e.to.y][e.to.dir]){
que.push(e.to);
inque[e.to.x][e.to.y][e.to.dir]=true;
if(++cnt[e.to.x][e.to.y][e.to.dir]>=n)  return true;
}
}
}
}
return false;
}
};
SPFA SMF;
int main()
{
int n,m,u,v,c,d,dir;
char s;
while(~scanf("%d%d",&n,&m)){
SMF.init(n,m);
scanf("%d%d%d%d%*c%c",&u,&v,&c,&d,&s);
switch(s){
case 'S':dir=1;
break;
case 'W':dir=0;
break;
case 'N':dir=3;
break;
case 'E':dir=2;
break;
}
SMF.spfa(Con(u,v,dir));
int ans=INF;
for(int i=0;i<4;++i){
ans=min(ans,SMF.d[c][d][i]);
}
printf("%d\n",(ans==INF?-1:ans));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: