算法提高课-搜索-双向广搜 AcWing 190. 字串变换:bfs、双向bfs、queue和unordered_map
生活随笔
收集整理的這篇文章主要介紹了
算法提高课-搜索-双向广搜 AcWing 190. 字串变换:bfs、双向bfs、queue和unordered_map
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目分析
來源:acwing
分析:
雙向廣搜主要用在最小步數模型(也稱狀態圖模型)里面,這里整個狀態空間一般是指數級別的,用雙向廣搜可以極大地提高運行效率。
雙向廣搜,顧名思義,就是從起點和終點都進行bfs搜索,然后兩者相遇的話,就代表找到了合適的從起點到終點的路徑。下圖展示了起點A和終點B之間能搜到的最小步數的計算過程。
ac代碼
#include<bits/stdc++.h> using namespace std; const int N = 6; int n; string a[N],b[N]; // 擴展函數 // 參數:擴展的隊列,到起點的距離,到終點的距離,規則,規則 //返回值:滿足條件的最小步數 int extend(queue<string>& q, unordered_map<string,int>& da, unordered_map<string, int>& db,string a[], string b[]){// 取出隊頭元素string t = q.front();q.pop();for(int i = 0; i < t.size(); i ++) // t從哪里開始擴展for(int j = 0; j < n; j ++) // 枚舉規則//如果t這個字符串的一段= 規則,比如= xyz,才可以替換if(t.substr(i, a[j].size()) == a[j]){// 變換之后的結果state:前面不變的部分+ 變化的部分 + 后面不變的部分// 比如abcd ,根據規則abc--> xu,變成 xud,這里的state就是xudstring state = t.substr(0,i) +b[j] + t.substr(i + a[j].size());// state狀態是否落到b里面去,兩個方向會師,返回最小步數if(db.count(state)) return da[t] + 1 + db[state];// 如果該狀態之前已擴展過,if(da.count(state)) continue;da[state] = da[t] + 1;q.push(state);}return 11;} // 從起點和終點來做bfs int bfs(string A, string B){queue<string> qa, qb; // 兩個方向的隊列//每個狀態到起點的距離da(哈希表),每個狀態到終點的距離db哈希表unordered_map<string, int> da, db; // qa從起點開始搜,qb從終點開始搜qa.push(A), da[A] = 0; // 起點A到起點的距離為0qb.push(B), db[B] = 0; // 終點B到終點B的距離為0// qa和qb都有值,說明可以擴展過來,否則說明是不相交的while(qa.size() && qb.size()){int t; // 記錄最小步數// 哪個方向的隊列的長度更小一些,空間更小一些,從該方向開始擴展,// 時間復雜度比較平滑,否則有1個點會超時if(qa.size() <= qb.size()) t = extend(qa, da, db, a, b);else t = extend(qb, db, da, b, a);// 如果最小步數在10步以內if( t <= 10) return t;}return 11; // 如果不連通或者最小步數>10,則返回大于10的數}int main(){string A, B;cin >> A >> B;// 讀入擴展規則,分別存在a數組和b數組while( cin >> a[n] >> b[n]) n ++;int step = bfs(A,B);if(step > 10) puts("NO ANSWER!");else cout << step << endl; }題目來源
https://www.acwing.com/problem/content/192/
總結
以上是生活随笔為你收集整理的算法提高课-搜索-双向广搜 AcWing 190. 字串变换:bfs、双向bfs、queue和unordered_map的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法提高课-搜索-双端队列广搜-AcWi
- 下一篇: 算法提高课-搜索-A*(A star)算