1495 例 2 孤島營救問題

2021-09-26 20:28:58 字數 1564 閱讀 8648

傳送門  //因為一本通上有乙個測試點錯了,所以給洛谷的測試

這題大部分都是用bfs + 狀壓去做,但是一本通裡把這題放在了最短路上,雖然用最短路的時間空間都比bfs要差,但是這是一道很好的去訓練分層最短路的題。

bfs版:

bfs把每個種類的鑰匙都單獨分成一層,然後根據我拿了鑰匙的狀態去找到我現在應該在的層,再bfs搜尋最短路。

#includeusing namespace std;

const int n = 12;

int dir[5][3]=,,,};

int e[n][n][n][n],key[n][n][n],dkey[n][n];

int vis[n][n][1<<14];

int n,m;

struct node

node(int x,int y,int k,int d):x(x),y(y),k(k),d(d){}

};int getkey(int x,int y)

int bfs()

} return -1;

}void read()

for(scanf("%d",&s);s--;)

} int main()

最短路版:

這裡涉及到的變化還蠻多的,我們要先算出最多邊數:1>>10*10*10=1024000;

把原來矩陣每個座標存成乙個點,再對可到鄰邊賦權值1,在建圖的時候,我們只要連線乙個雙向邊即可,假設j是從i左移一格,那麼i就是j右移一格。上下同理。值得注意的是,我們每次在一層的時候,在沒有鑰匙i的時候,我們需要把i鑰匙鎖在的點u,連線到有了i鑰匙的那一層對應的位置上v,權值是0,這樣就建成了1>>種類 的圖,並且圖直接有連線。最後跑一遍最短路即可。

ps:要記錄總層數的總點數,之後dis的初始化時所有點。

//分層求最短路 

#includeusing namespace std;

const int n = 12;

const int m = 1024100;

const int inf = 0x3f3f3f3f;

typedef pairp;

struct keynkey[n][20];//key[i][j] 種類為i的鑰匙第j把的座標

int n,m,p,s,k,cnt,layer,nn,nsum;//n寬,m長,p種類,s總鑰匙數,k總障礙數,cnt計數器,layer層數,nn每層的點,nsum總點數

int num[n][n],fg[200][200];

int head[m],nex[m],ver[m],edge[m];

int hadk[n],kn[n],vis[m],dis[m];

void add(int x,int y,int w)

void read()

scanf("%d",&s);

for(int i = 1,q;i <= s;i++)

}void build()

} }}void spfa()

}} }}

void solve()

int main()

題解 孤島營救問題

luogu p4011 孤島營救問題 loj 6121.網路流 24 題 孤島營救問題 乙個 n times m 的矩陣,每個單元位置用乙個有序數對 行號,列號 表示。上下左右四個方向相鄰的兩個單元格之間存在一下情況 其中某種條件分為 p 類要素,使一種條件成立的要素相同,不同條件成立的要素不同。初...

狀壓 孤島營救問題

題目鏈結 題目描述 1944 年,特種兵麥克接到國防部的命令,要求立即趕赴太平洋上的乙個孤島,營救被敵軍俘虜的大兵瑞恩。瑞恩被關押在乙個迷宮裡,迷宮地形複雜,但幸好麥克得到了迷宮的地形圖。迷宮的外形是乙個長方形,其南北方向被劃分為 n 行,東西方向被劃分為 m 列,於是整個迷宮被劃分為 n time...

codevs1911 孤島營救問題

1944 年,特種兵麥克接到國防部的命令,要求立即趕赴太平洋上的乙個孤島,營救被敵軍俘虜的大兵瑞恩。瑞恩被關押在乙個迷宮裡,迷宮地形複雜,但幸好麥克得到了迷宮的地形圖。迷宮的外形是乙個長方形,其南北方向被劃分為n 行,東西方向被劃分為m列,於是整個迷宮被劃分為n m 個單元。每乙個單元的位置可用乙個...