1944 年,特種兵麥克接到國防部的命令,要求立即趕赴太平洋上的乙個孤島,營救被敵軍俘虜的大兵瑞恩。瑞恩被關押在乙個迷宮裡,迷宮地形複雜,但幸好麥克得到了迷宮的地形圖。迷宮的外形是乙個長方形,其南北方向被劃分為 n 行,東西方向被劃分為 m 列,於是整個迷宮被劃分為 n×m 個單元。每乙個單元的位置可用乙個有序數對(單元的行號,單元的列號)來表示。南北或東西方向相鄰的 2 個單元之間可能互通,也可能有一扇鎖著的門,或者是一堵不可逾越的牆。迷宮中有一些單元存放著鑰匙,並且所有的門被分成p 類,開啟同一類的門的鑰匙相同,不同類門的鑰匙不同。
大兵瑞恩被關押在迷宮的東南角,即(n,m) 單元裡,並已經昏迷。迷宮只有乙個入口,在西北角。也就是說,麥克可以直接進入 (1,1)單元。另外,麥克從乙個單元移動到另乙個相鄰單元的時間為 1,拿取所在單元的鑰匙的時間以及用鑰匙開門的時間可忽略不計。
試設計乙個演算法,幫助麥克以最快的方式到達瑞恩所在單元,營救大兵瑞恩。
bfs+狀態壓縮
s才14果斷狀壓拿了多少把鑰匙。
設vis[x][y][t]表示到(x,y)且鑰匙狀態為t時的最短時間,很顯然每個位置每個狀態只能走一次。
#include#include#include#include#includeusing namespace std;
const int inf=1<<30;
const int maxn=12;
const int dx=,dy=;
int n,m,p;
vectorkey[maxn][maxn];
int ma[maxn][maxn][maxn][maxn];
int vis[maxn][maxn][(1<<14)+10];
struct u;
queueq;
void bfs()
);// printf("q: %d %d %d - %d\n",nx,ny,nt,vis[nx][ny][nt]);}}
}}int main()
int s;scanf("%d",&s);
for(int i=1;i<=s;i++)
bfs();
int ans=inf;
for(int i=0,imax=1
else puts("-1");
return 0;
}
洛谷P4011 孤島營救問題(狀壓 BFS)
傳送門 和網路流有半毛錢關係麼 可以發現 n,m,p 都特別小,那麼考慮狀壓,每乙個狀態表示位置以及鑰匙的擁有情況,然後每次因為只能走一步,所以可以用bfs求出最優解 然後是某大佬說的注意點 每個點可以有很多鑰匙,而且初始點也有可能有鑰匙 1 minamoto 2 include3 include4...
洛谷4011 孤島營救問題(狀壓SPFA)
點此看題面 大致題意 有乙個 n m 的四聯通迷宮,相鄰兩個可能互通,可能有一扇門,也可能有一堵牆。對於第 i 類的門,你需要有第 i 類的鑰匙才可以通過。問你從 1,1 到達 n,m 的最短路。看到種類數 10 應該不難想到狀壓吧!而且,我們還可以給每個格仔乙個編號 計算方法 pos x,y x ...
P4011 孤島營救問題
p4011 孤島營救問題 輸入 449 9121 3212 2202 1220 2131 0233 3024 3413 2330 3343 0434 4022 1242 1輸出 14 原題太長我就不貼了,簡單敘述一下 乙個n m的迷宮,每個單元格之間可能有門或者牆,也可能啥也沒有。門和牆的總數為k ...