洛谷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; }
相关文章推荐
- 洛谷P1126机器人搬重物[BFS]
- 洛谷P1126 机器人搬重物
- 洛谷 P1126 机器人搬重物
- 洛谷P1126 机器人搬重物
- 洛谷—— P1126 机器人搬重物
- 洛谷P1126 机器人搬重物
- 【BFS】洛谷1126机器人搬重物_water(划掉)
- 洛谷P1126 机器人搬重物
- 华容道 洛谷1979 bfs+spfa
- P1126 机器人搬重物
- 洛谷 P1979 华容道[noip2013] (bfs+spfa)
- 【p1126-机器人搬重物】解题记录
- P1126 机器人搬重物
- P1126 机器人搬重物
- 洛谷 P3953 逛公园【spfa+记忆化dfs+bfs】
- 洛谷 P2296 寻找道路【bfs+spfa】
- 洛谷 1126 机器人搬重物
- P1126 机器人搬重物
- 机器人搬重物(BFS)
- 【洛谷1593】【模板】template负环 递归SPFA判负环