hdu1195 Open the Lock 双向BFS

  1. 看http://blog.csdn.net/liuqiyao_01/article/details/8892261终于看懂双向BFS的具体做法了。
  2. 准备两个队列,分别放出发点和终点。
  3. 之后while()
  4. {
  5.    BFS(0)
  6.    BFS(1)
  7.  //分别代表两个点出发遍历。
  8. }
  9. 对于每一个bfs,首先看看是否上一个bfs已经找到答案了,如果找到了,这个就不需要遍历了。
  10. 之后就开始遍历,我们一般的就是while(!que.empty()),但是这个我们需要再加一个判定条件,因为双重遍历,如果不加,我们就
  11. 一次性直接把某一个BFS遍历完了,根本不需要第二个遍历了。我们需要一层一层遍历,对于当前BFS我们只遍历一层,之后让另外一个
  12. BFS进行遍历。所以说当前BFS,我们先取出一个来,q1。我们知道q1的步数是firststep,我们本次就之便利step次数的。也就是
  13. while(!que.empty()&&que.front().step==firststep)。我们只遍历这一层。
  14. 如果对于当前front的状态,另一个BFS已经到达了,也就是另一个的BFS的vis记录已经访问了,这代表我们两个出发点成功搭线了,
  15. 直接输出即可。这里我们用vis1,2分别记录两个BFS到达某个状态的步数。那么就是两个vis相加输出即可。


  16. #include <iostream>  
  17. #include <cstdio>  
  18. #include <queue>  
  19. #include <cstring>  
  20. using namespace std;  
  21.   
  22. struct node  
  23. {  
  24.     int num[4];  
  25.     int step;  
  26. };  
  27. queue<node> q[2];  
  28. int vis[2][10][10][10][10];  
  29. int ansnum[4];  
  30. int ans;  
  31.   
  32. void init()  
  33. {  
  34.     ans = -1;  
  35.     memset(vis, -1, sizeof(vis));  
  36.     while (!q[0].empty()) q[0].pop();  
  37.     while (!q[1].empty()) q[1].pop();  
  38. }  
  39.   
  40. bool istrue(node x, int i)  
  41. {  
  42.     if (vis[1^i][x.num[0]][x.num[1]][x.num[2]][x.num[3]] != -1)  
  43.         return true;  
  44.     return false;  
  45. }  
  46.   
  47. bool judge(node x, int i)  
  48. {  
  49.     if (vis[i][x.num[0]][x.num[1]][x.num[2]][x.num[3]] != -1) return false;  
  50.     return true;  
  51. }  
  52.   
  53. node change(node a, int b)  
  54. {  
  55.     a.step ++;  
  56.   
  57.     if (b < 4)       // +  
  58.     {  
  59.         if (a.num[b] == 9) a.num[b] = 1;  
  60.         else a.num[b] ++;  
  61.     }  
  62.     else if (b < 8)  // -  
  63.     {  
  64.         if (a.num[b%4] == 1) a.num[b%4] = 9;  
  65.         else a.num[b%4] = a.num[b%4] - 1;  
  66.     }  
  67.     else    // 换  
  68.     {  
  69.         int tmp;  
  70.         b %= 4;  
  71.         tmp = a.num[b];  
  72.         a.num[b] = a.num[b+1];  
  73.         a.num[b+1] = tmp;  
  74.     }  
  75.   
  76.     return a;  
  77. }  
  78.   
  79. void bfs(int j)  
  80. {  
  81.     node now, next;  
  82.     if (ans != -1 || q[j].empty()) return ;  
  83.     int first = q[j].front().step;  
  84.     while (!q[j].empty() && q[j].front().step == first)  
  85.     {  
  86.         now = q[j].front();  
  87.         q[j].pop();  
  88.   
  89.         if (istrue(now, j))  
  90.         {  
  91.             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]];  
  92.             return ;  
  93.         }  
  94.   
  95.         for (int i = 0; i < 11; i++)  
  96.         {  
  97.             next = change(now, i);  
  98.             if (judge(next, j))  
  99.             {  
  100.                 vis[j][next.num[0]][next.num[1]][next.num[2]][next.num[3]] = next.step;  
  101.                 q[j].push(next);  
  102.             }  
  103.         }  
  104.     }  
  105. }  
  106.   
  107. void db_bfs()  
  108. {  
  109.     while (ans == -1)  
  110.     {  
  111.         bfs(0);  
  112.         bfs(1);  
  113.     }  
  114. }  
  115.   
  116. int main()  
  117. {  
  118.     int T;  
  119.     scanf("%d", &T);  
  120.     while (T--)  
  121.     {  
  122.         init();  
  123.         int a, b;  
  124.         node now0, now1;  
  125.         scanf("%d %d", &a, &b);  
  126.   
  127.         for (int i=3; i>=0; i--)  
  128.         {  
  129.             now0.num[i] = a % 10;  
  130.             now1.num[i] = b % 10;  
  131.             a /= 10;  
  132.             b /= 10;  
  133.         }  
  134.         now0.step = 0;  
  135.         q[0].push(now0);  
  136.         vis[0][now0.num[0]][now0.num[1]][now0.num[2]][now0.num[3]] = 0;  
  137.         now1.step = 0;  
  138.         q[1].push(now1);  
  139.         vis[1][now1.num[0]][now1.num[1]][now1.num[2]][now1.num[3]] = 0;  
  140.   
  141.         db_bfs();  
  142.   
  143.         printf("%d\n", ans);  
  144.     }  
  145.     return 0;  
  146. }  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值