生活随笔
收集整理的這篇文章主要介紹了
图论 —— 图的搜索
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
【概述】
圖的搜索問題,是給出一個抽象的字符矩陣代表一張圖,根據(jù)根據(jù)題目要求,對圖進(jìn)行搜索,關(guān)于搜索算法:點(diǎn)擊這里
根據(jù)搜索方法的不同,分為深度優(yōu)先遍歷(DFS)、廣度優(yōu)先遍歷(BFS),兩者時間復(fù)雜度都是 O(N*N),通常采用深度優(yōu)先遍歷。
【深度優(yōu)先遍歷】
圖的深度優(yōu)先遍歷的基本過程為:
從圖中某個頂點(diǎn) v0 出發(fā),首先訪問 v0訪問結(jié)點(diǎn) v0 的第一個鄰接點(diǎn),以這個鄰接點(diǎn) vt 作為一個新節(jié)點(diǎn),訪問 vt 所有鄰接點(diǎn),直到以 vt 出發(fā)的所有節(jié)點(diǎn)都被訪問回溯到 v0 的下一個未被訪問過的鄰接點(diǎn),以這個鄰結(jié)點(diǎn)為新節(jié)點(diǎn),重復(fù)步驟 2,直到圖中所有與 v0 相通的所有節(jié)點(diǎn)都被訪問若此時圖中仍有未被訪問的結(jié)點(diǎn),則另選圖中的一個未被訪問的頂點(diǎn)作為起始點(diǎn),重復(fù)步驟 1,直到圖中的所有節(jié)點(diǎn)均被訪問
其基本框架為:
int vis[N];
void DFS(int i) {for(所有i的鄰接點(diǎn)j) {if(!vis[j]) {if(j == 目標(biāo)狀態(tài))return true;vis[j]=true;dfs(j);}}
}
【廣度優(yōu)先遍歷】
圖的廣度優(yōu)先遍歷的基本過程為:
從圖中某個頂點(diǎn) v0 出發(fā),首先訪問 v0,將 v0 加入隊(duì)列將隊(duì)首元素的未被訪問過的鄰接點(diǎn)加入隊(duì)列,訪問隊(duì)首元素并將隊(duì)首元素出隊(duì),直到隊(duì)列為空若此時圖中仍有未被訪問的結(jié)點(diǎn),則另選圖中的一個未被訪問的頂點(diǎn)作為起始點(diǎn),重復(fù)步驟 1,直到圖中的所有節(jié)點(diǎn)均被訪問過。
其基本框架為:
bool vis[N];
void BFS(int start) {queue<int> Q;Q.push(start);vis[s]=true;while(!Q.empty()) {int x=Q.front();Q.pop();if(x==目標(biāo)狀態(tài)) {...}for(所有i的鄰接點(diǎn)j) {if(!vis[j]) {Q.push(j);vis[j]=true;}}}
}
【奇偶剪枝】
對于給出的字符矩陣,在搜索過程中,利用奇偶剪枝能極大的降低時間復(fù)雜度。
1.內(nèi)容
假設(shè)起點(diǎn)為(sx,sy),終點(diǎn)為(ex,ey),給定 t 步恰好走到終點(diǎn),如圖所示(“|”豎走,“—”橫走,“+”轉(zhuǎn)彎),易證 abs(ex-sx)+abs(ey-sy) 為此問題類中任意情況下,起點(diǎn)到終點(diǎn)的最短步數(shù),記做 step,此處 step1=8;
如圖,為一般情況下非最短路徑的任意走法舉例,step2=14;step2-step1=6,偏移路徑為 6
推廣:若 t-[abs(ex-sx)+abs(ey-sy)] 結(jié)果為奇數(shù),則無法在 t 步恰好到達(dá),返回 false;反之,若結(jié)果為偶數(shù),則可以在 t 步恰好到達(dá),返回 true。
2.應(yīng)用
如圖,沒障礙物#時,S到E的最短路長為6,但是當(dāng)有障礙物時,就要繞行了。
如圖,黑色為最短路徑,當(dāng)他繞行(紅色加藍(lán)色部分)時,其中藍(lán)色部分其實(shí)還是最短路徑部分平移來的,所以多走的步數(shù)也就是紅色部分。對于紅色部分我們可以分為兩部分,一部分是遠(yuǎn)離最短路徑的步數(shù),另一部分是回到最短路徑的部分,他們一定是對稱的,所以多走的步數(shù)一定是偶數(shù)。
所以,當(dāng)問走 x 步能否到達(dá) e,就算出最短路徑長 y,如果 x-y 是偶數(shù)就能到達(dá),否則不能到達(dá)。
【例題】
1.深度優(yōu)先遍歷
紅與黑(信息學(xué)奧賽一本通-T1216):點(diǎn)擊這里
同題:Red and Black(HDU-1312):點(diǎn)擊這里迷宮(洛谷-P1605):點(diǎn)擊這里迷宮(信息學(xué)奧賽一本通-T1215):點(diǎn)擊這里花生采摘(洛谷-P1086):點(diǎn)擊這里LETTERS(信息學(xué)奧賽一本通-T1212):點(diǎn)擊這里棋盤問題(信息學(xué)奧賽一本通-T1217):點(diǎn)擊這里Avoid The Lakes(POJ-3620):點(diǎn)擊這里Cat Snuke and a Voyage(AtCoder-2660):點(diǎn)擊這里Applese 走方格(2019牛客寒假算法基礎(chǔ)集訓(xùn)營 Day4-B):點(diǎn)擊這里Pusher(HDU-2821):點(diǎn)擊這里填涂顏色(洛谷-P1162):點(diǎn)擊這里01迷宮(洛谷-P1141)(記憶化):點(diǎn)擊這里Tempter of the Bone(HDU-1010)(奇偶剪枝):點(diǎn)擊這里
2.廣度優(yōu)先遍歷
仙島求藥(信息學(xué)奧賽一本通-T1251):點(diǎn)擊這里走迷宮(信息學(xué)奧賽一本通-T1252):點(diǎn)擊這里走出迷宮(信息學(xué)奧賽一本通-T1254):點(diǎn)擊這里獻(xiàn)給阿爾吉儂的花束(信息學(xué)奧賽一本通-T1256):點(diǎn)擊這里圍成面積(信息學(xué)奧賽一本通-T1359):點(diǎn)擊這里迷宮(2019牛客寒假算法基礎(chǔ)集訓(xùn)營 Day6-J):點(diǎn)擊這里The Castle(信息學(xué)奧賽一本通-T1250):點(diǎn)擊這里Fennec VS. Snuke(AtCoder-2655):點(diǎn)擊這里Rescue(HDU-1242)(終點(diǎn)找起點(diǎn)):點(diǎn)擊這里Catch him(HDU-2351)(塊狀bfs):點(diǎn)擊這里迷宮問題(信息學(xué)奧賽一本通-T1255)(遞歸輸出):點(diǎn)擊這里Navigating the City(POJ-2435)(通過隊(duì)列輸出):點(diǎn)擊這里Dungeon Master(信息學(xué)奧賽一本通-T1248)(三維bfs):點(diǎn)擊這里Applese 走迷宮(2019牛客寒假算法基礎(chǔ)集訓(xùn)營 Day4-C)(三維bfs):點(diǎn)擊這里炫酷迷宮(2019牛客寒假算法基礎(chǔ)集訓(xùn)營 Day5-C)(構(gòu)造+bfs):點(diǎn)擊這里機(jī)器人搬重物(洛谷-P1126)(預(yù)處理):點(diǎn)擊這里Lilypad Pondg(POJ-3171)(兩次bfs+預(yù)處理):點(diǎn)擊這里The Grove(POJ-3182)(射線法):點(diǎn)擊這里Meteor Shower(POJ-3669)(起點(diǎn)的處理):點(diǎn)擊這里
總結(jié)
以上是生活随笔為你收集整理的图论 —— 图的搜索的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。