- 看http://blog.csdn.net/liuqiyao_01/article/details/8892261终于看懂双向BFS的具体做法了。
- 准备两个队列,分别放出发点和终点。
- 之后while()
- {
- BFS(0)
- BFS(1)
- //分别代表两个点出发遍历。
- }
- 对于每一个bfs,首先看看是否上一个bfs已经找到答案了,如果找到了,这个就不需要遍历了。
- 之后就开始遍历,我们一般的就是while(!que.empty()),但是这个我们需要再加一个判定条件,因为双重遍历,如果不加,我们就
- 一次性直接把某一个BFS遍历完了,根本不需要第二个遍历了。我们需要一层一层遍历,对于当前BFS我们只遍历一层,之后让另外一个
- BFS进行遍历。所以说当前BFS,我们先取出一个来,q1。我们知道q1的步数是firststep,我们本次就之便利step次数的。也就是
- while(!que.empty()&&que.front().step==firststep)。我们只遍历这一层。
- 如果对于当前front的状态,另一个BFS已经到达了,也就是另一个的BFS的vis记录已经访问了,这代表我们两个出发点成功搭线了,
- 直接输出即可。这里我们用vis1,2分别记录两个BFS到达某个状态的步数。那么就是两个vis相加输出即可。
-
-
- #include <iostream>
- #include <cstdio>
- #include <queue>
- #include <cstring>
- using namespace std;
- struct node
- {
- int num[4];
- int step;
- };
- queue<node> q[2];
- int vis[2][10][10][10][10];
- int ansnum[4];
- int ans;
- void init()
- {
- ans = -1;
- memset(vis, -1, sizeof(vis));
- while (!q[0].empty()) q[0].pop();
- while (!q[1].empty()) q[1].pop();
- }
- bool istrue(node x, int i)
- {
- if (vis[1^i][x.num[0]][x.num[1]][x.num[2]][x.num[3]] != -1)
- return true;
- return false;
- }
- bool judge(node x, int i)
- {
- if (vis[i][x.num[0]][x.num[1]][x.num[2]][x.num[3]] != -1) return false;
- return true;
- }
- node change(node a, int b)
- {
- a.step ++;
- if (b < 4) // +
- {
- if (a.num[b] == 9) a.num[b] = 1;
- else a.num[b] ++;
- }
- else if (b < 8) // -
- {
- if (a.num[b%4] == 1) a.num[b%4] = 9;
- else a.num[b%4] = a.num[b%4] - 1;
- }
- else // 换
- {
- int tmp;
- b %= 4;
- tmp = a.num[b];
- a.num[b] = a.num[b+1];
- a.num[b+1] = tmp;
- }
- return a;
- }
- void bfs(int j)
- {
- node now, next;
- if (ans != -1 || q[j].empty()) return ;
- int first = q[j].front().step;
- while (!q[j].empty() && q[j].front().step == first)
- {
- now = q[j].front();
- q[j].pop();
- if (istrue(now, j))
- {
- ans = vis[j][now.num[0]][now.num[1]][now.num[2]][now.num[3]] + vis[1^j][now.num[0]][now.num[1]][now.num[2]][now.num[3]];
- return ;
- }
- for (int i = 0; i < 11; i++)
- {
- next = change(now, i);
- if (judge(next, j))
- {
- vis[j][next.num[0]][next.num[1]][next.num[2]][next.num[3]] = next.step;
- q[j].push(next);
- }
- }
- }
- }
- void db_bfs()
- {
- while (ans == -1)
- {
- bfs(0);
- bfs(1);
- }
- }
- int main()
- {
- int T;
- scanf("%d", &T);
- while (T--)
- {
- init();
- int a, b;
- node now0, now1;
- scanf("%d %d", &a, &b);
- for (int i=3; i>=0; i--)
- {
- now0.num[i] = a % 10;
- now1.num[i] = b % 10;
- a /= 10;
- b /= 10;
- }
- now0.step = 0;
- q[0].push(now0);
- vis[0][now0.num[0]][now0.num[1]][now0.num[2]][now0.num[3]] = 0;
- now1.step = 0;
- q[1].push(now1);
- vis[1][now1.num[0]][now1.num[1]][now1.num[2]][now1.num[3]] = 0;
- db_bfs();
- printf("%d\n", ans);
- }
- return 0;
- }
hdu1195 Open the Lock 双向BFS
最新推荐文章于 2024-01-25 18:22:08 发布