HDOJ1195 双向BFS //单向也可以过

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ1195 双向BFS //单向也可以过相关的知识,希望对你有一定的参考价值。

  1 #include<cstdio>
  2 #include<map>
  3 #include<vector>
  4 #include<stack>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<cstring>
  8 #include<cmath>
  9 #include<queue>
 10 #include<cstdlib> 
 11 #define PI acos(-1.0)
 12 using namespace std;
 13 typedef long long ll;
 14 const ll mood=1e9+7;
 15 const double eps=1e-9;
 16 const int N=1e4+10;
 17 const int MAXN=510;
 18 struct node{   
 19     string password;
 20     int cnt;
 21     }now,tmp;      
 22 string beg,end;   
 23 map<string,int>back_vis;   
 24 map<string,int>vis;   
 25 queue<struct node>q;   
 26 queue<struct node>back_q;      
 27 int back_bfs(int n)//反向BFS,每次只搜一层,即第n层   
 28 {   
 29     while(back_q.front().cnt<=n)   
 30     {   
 31         now=back_q.front();   
 32         back_q.pop();   
 33         for(int i=0;i<4;i++)   
 34         {   //各个位-1\
 35                tmp=now;
 36             if(tmp.password[i]!=1)   
 37                 tmp.password[i]--;   
 38             else   tmp.password[i]=9;   
 39             if(vis.find(tmp.password)!=vis.end())//判断是否在正向队列中找到   
 40             return tmp.cnt+1+vis[tmp.password];   
 41             if(back_vis.find(tmp.password)==back_vis.end())   
 42             {   
 43                 tmp.cnt++;   
 44                 back_q.push(tmp);
 45                 back_vis[tmp.password]=tmp.cnt;   
 46             }   //各个位+1   
 47             tmp=now;   
 48             if(tmp.password[i]!=9)   tmp.password[i]++;   
 49             else   tmp.password[i]=1;   
 50             if(vis.find(tmp.password)!=vis.end())//判断是否在正向队列中找到   
 51                 return tmp.cnt+1+vis[tmp.password];   
 52             if(back_vis.find(tmp.password)==back_vis.end())   
 53             {   
 54                 tmp.cnt++;   
 55                 back_q.push(tmp);   
 56                 back_vis[tmp.password]=tmp.cnt;   
 57             }   
 58         }   
 59         for(int i=0;i<3;i++)   
 60         {
 61             tmp=now;
 62             swap(tmp.password[i],tmp.password[i+1]);
 63             if(vis.find(tmp.password)!=vis.end())//判断是否在正向队列中找到   、
 64             return tmp.cnt+1+vis[tmp.password];   
 65             if(back_vis.find(tmp.password)==back_vis.end())   
 66             {   tmp.cnt++;   back_q.push(tmp);   back_vis[tmp.password]=tmp.cnt;   }
 67         }   
 68     }   
 69     return -1;   
 70 }      
 71 int bfs()   
 72 {   
 73     while(!q.empty())   
 74         q.pop();//清空正向BFS的队列   
 75     now.password=beg;   
 76     now.cnt=0;   
 77     q.push(now);   
 78     vis[beg]=0;   
 79     while(!q.empty())   
 80     {   
 81         int n=q.front().cnt;   
 82         while(q.front().cnt<=n)
 83         {   
 84             now=q.front();   q.pop();   
 85             for(int i=0;i<4;i++)   
 86             {   //各个位-1   
 87                 tmp=now;
 88                 if(tmp.password[i]!=1)
 89                        tmp.password[i]--;   
 90                 else   tmp.password[i]=9;   
 91                 if(back_vis.find(tmp.password)!=back_vis.end())//判断是否在反向队列中找到   
 92                 return tmp.cnt+1+back_vis[tmp.password];
 93                 if(vis.find(tmp.password)==vis.end())   
 94                 {   tmp.cnt++;   q.push(tmp);   vis[tmp.password]=tmp.cnt;   }   //各个位+1   
 95                 tmp=now;   
 96                 if(tmp.password[i]!=9)   tmp.password[i]++;
 97                 else   tmp.password[i]=1;   
 98                 if(back_vis.find(tmp.password)!=back_vis.end())//判断是否在反向队列中找到   
 99                 return tmp.cnt+1+back_vis[tmp.password];   
100                 if(vis.find(tmp.password)==vis.end())
101                 {   tmp.cnt++;   q.push(tmp);   vis[tmp.password]=tmp.cnt;   }   
102             }   
103             for(int i=0;i<3;i++)   
104             {   
105                 tmp=now;   
106                 swap(tmp.password[i],tmp.password[i+1]);   
107                 if(back_vis.find(tmp.password)!=back_vis.end())//判断是否在反向队列中找到   
108                 return tmp.cnt+1+back_vis[tmp.password];   
109                 if(vis.find(tmp.password)==vis.end())   {   
110                     tmp.cnt++;   q.push(tmp);   
111                     vis[tmp.password]=tmp.cnt;   
112                 }   
113             }   
114         }   
115         int ret=back_bfs(now.cnt);   
116         if(ret!=-1)   
117             return ret;   
118     }   
119 }      
120 int main(){   
121     int t;   
122     while(cin>>t)   
123     {   
124         while(t--)   
125         {   
126             cin>>beg;   
127             cin>>end;   
128             vis.clear();//清空map   
129             back_vis.clear();//清空map   
130             while(!back_q.empty())   
131             back_q.pop();//清空反向BFS的队列   
132             now.password=end;   
133             now.cnt=0;   
134             back_q.push(now);   
135             back_vis[end]=0;//将反向BFS的起始点入队列标记   
136             int ret=bfs();   
137             cout<<ret<<endl;   
138         }   
139     }   
140     return 0;   
141 }    

 

以上是关于HDOJ1195 双向BFS //单向也可以过的主要内容,如果未能解决你的问题,请参考以下文章

HDU3085nightmare2 双向BFS

POJ1915Knight Moves(单向BFS + 双向BFS)

双向BFS统计

hdoj2612 Find a way (bfs)

HDOJ-1043 Eight

HDU 1043 Eight(双向BFS+康托展开)