雙向BFS NOIP2002 字串變換

2022-07-08 19:51:13 字數 2020 閱讀 5074

如果目標也已知的話,用雙向bfs能很大提高速度

單向時,是 b^len的擴充套件。

雙向的話,2*b^(len/2)  快了很多,特別是分支因子b較大時

至於實現上,網上有些做法是用兩個佇列,交替節點搜尋 ×,如下面的偽**:

while(!empty())

但這種做法是有問題的,如下面的圖:

求s-t的最短路,交替節點搜尋(一次正向節點,一次反向節點)時

step 1 : s –> 1 , 2

step 2 : t –> 3 , 4

step 3 : 1 –> 5

step 4 : 3 –> 5   返回最短路為4,錯誤的,事實是3,s-2-4-t

我想,正確做法的是交替逐層搜尋,保證了不會先遇到非最優解就跳出,而是檢查完該層所有節點,得到最優值

也即如果該層搜尋遇到了對方已經訪問過的,那麼已經搜尋過的層數就是答案了,可以跳出了,以後不會更優的了。

當某一邊佇列空時就無解了。

優化:提供速度的關鍵在於使狀態擴充套件得少一些,所以優先選擇佇列長度較少的去擴充套件,保持兩邊佇列長度平衡。這比較適合於兩邊的擴充套件情況不同時,一邊擴充套件得快,一邊擴充套件得慢。如果兩邊擴充套件情況一樣時,加了後效果不大,不過加了也沒事。

無向圖時,兩邊擴充套件情況類似。有向圖時,注意反向的擴充套件是反過來x->y(noip2002g2字串變換)

/*

雙向bfs:

1.正向搜尋:從初始結點向目標結點方向搜尋,按照正向規則(a$->b$)變換。

2.逆向搜尋:從目標結點向初始結點方向搜尋,按照逆向規則(b$->a$)變換。

當兩個方向的搜尋生成同一子結點時終止此搜尋過程(變換的總步數為此時兩個方向bfs的步數總和)。

雙向搜尋通常有兩種方法:

1. 兩個方向交替擴充套件。

2. 選擇結點個數較少的那個方向先擴充套件。

方法2克服了兩方向結點的生成速度不平衡的狀態,明顯提高了效率。本程式使用方法1,兩個方向交替bfs,進行正反規則變換。

*/#include #include #include #include using namespace std;

struct node

}q1[20000], q2[20000];

int h1, r1, h2, r2; //h1,r1...h2,r2,分別儲存起始和目標兩個狀態的佇列頭和尾

char s1[6][25], s2[6][25]; //儲存變換規則

int n,min=100; //min儲存最少規則變換次數

void copy2(int start, int use) //逆向搜尋,當q2搜尋到逆向規則匹配的字串b$的時候,進行替換

for(j = 0; s1[use][j] != '\0'; j++, i++)

for(j = start + strlen(s2[use]); q2[h2].str[j] != '\0'; j++, i++)

//cout<

for(i = 0; i < strlen(q1[h1].str); i++)}}

h1++; //正向一遍bfs,搜尋完所有規則之後,隊首元素出隊

for(i = 0; i < strlen(q2[h2].str); i++) //加快搜尋的速度,同理從目標開始,方向,並根據逆向規則進行bfs}}

h2++;

}}int main()

work();

printf("no answer!\n");

return 0;

}

noip2002 字串變換 (雙向寬搜,交替擴充套件)

p1124字串變換 accepted 標籤 搜尋 搜尋與剪枝 noip提高組2002 已知有兩個字串 a b 及一組字串變換的規則 至多6個規則 a1 b1 a2 b2 規則的含義為 在 a 中的子串 a1 可以變換為 b1 a2 可以變換為 b2 例如 a abcd b xyz 變換規則為 abc...

NOIP2002 字串變換

一道難得的搜尋好題,題目大意很簡單,這裡不再贅述,主要說一下思路 當然普通的bfs答案是正確的,但是在ch上評測會tle乙個點,所以我們採用效率更高的雙向bfs 從初始狀態和目標狀態分別搜尋,建立兩個佇列,分別擴充套件狀態。如果乙個佇列擴充套件的狀態已經被另乙個佇列搜尋過了,那麼便出現答案了。另外,...

NOIP2002 Luogu1032 字串變換

problem solution codes 思路就是對於每個狀態下的字串,列舉可以替換的部分替換作為下乙個新的狀態。include include include include using namespace std int n 1,flag string a,b,ai 1010 bi 1010...