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 //单向也可以过的主要内容,如果未能解决你的问题,请参考以下文章