洛谷P1126 機械人搬重物 BFS SPFA

2021-08-06 02:39:07 字數 2548 閱讀 6792

機械人移動學會(rmi)現在正嘗試用機械人搬運物品。機械人的形狀是乙個直徑1.6公尺的球。在試驗階段,機械人被用於在乙個儲藏室中搬運貨物。儲藏室是乙個n*m的網格,有些格仔為不可移動的障礙。機械人的中心總是在格點上,當然,機械人必須在最短的時間內把物品搬運到指定的地方。機械人接受的指令有:向前移動1步(creep);向前移動2步(walk);向前移動3步(run);向左轉(left);向右轉(right)。每個指令所需要的時間為1秒。請你計算一下機械人完成任務所需的最少時間。

輸入的第一行為兩個正整數n,m(n,m<=50),下面n行是儲藏室的構造,0表示無障礙,1表示有障礙,數字之間用乙個空格隔開。接著一行有四個整數和乙個大寫字母,分別為起始點和目標點左上角網格的行與列,起始時的面對方向(東e,南s,西w,北n),數與數,數與字母之間均用乙個空格隔開。終點的面向方向是任意的。

乙個整數,表示機械人完成任務所需的最少時間。如果無法到達,輸出-1。

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

12
很明顯可以用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可以承受!

注意初始化,不能達到的點不再處理!

#include 

#include

#include

#include

#include

#include

#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]=;

const

int yy[4]=;

struct con

};struct edge;

};struct spfa}}

for(int i=0;i<55;++i)}}

bool canwalk;

edges.clear();

for(int i=1;ifor(int j=1;jif(!mp[i][j])else}}

}}}}

void addedge(con from,con to,int dist)

bool spfa(con s)

que.pop();

inque[temp.x][temp.y][temp.dir]=false;

for(int i=0;iif(d[e.to.x][e.to.y][e.to.dir]>d[temp.x][temp.y][temp.dir]+e.dist)}}

}return

false;

}};spfa smf;

int main()

smf.spfa(con(u,v,dir));

int ans=inf;

for(int i=0;i<4;++i)

printf("%d\n",(ans==inf?-1:ans));

}return

0;}

洛谷P1126 機械人搬重物

機械人移動學會 rmi 現在正嘗試用機械人搬運物品。機械人的形狀是乙個直徑1.6公尺的球。在試驗階段,機械人被用於在乙個儲藏室中搬運貨物。儲藏室是乙個n m的網格,有些格仔為不可移動的障礙。機械人的中心總是在格點上,當然,機械人必須在最短的時間內把物品搬運到指定的地方。機械人接受的指令有 向前移動1...

洛谷P1126 機械人搬重物

機械人移動學會 rmi 現在正嘗試用機械人搬運物品。機械人的形狀是乙個直徑 1.6 公尺的球。在試驗階段,機械人被用於在乙個儲藏室中搬運貨物。儲藏室是乙個 n m 的網格,有些格仔為不可移動的障礙。機械人的中心總是在格點上,當然,機械人必須在最短的時間內把物品搬運到指定的地方。機械人接受的指令有 向...

P1126機械人搬重物 洛谷

機械人移動學會 rmi 現在正嘗試用機械人搬運物品。機械人的形狀是乙個直徑 1.6 公尺的球。在試驗階段,機械人被用於在乙個儲藏室中搬運貨物。儲藏室是乙個 n mn times mn m 的網格,有些格仔為不可移動的障礙。機械人的中心總是在格點上,當然,機械人必須在最短的時間內把物品搬運到指定的地方...