参考书籍《算法竞赛入门到进阶》
宽度优先搜索(又称广度优先搜索)是算法竞赛基础中的基础,是最简便的图的搜索算法之一。这一算法将成为日后学习Dijkstra单源最短路径算法和Prim最小生成树算法的基础。
hdu1312 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1312
典型迷宫题,直接宽搜即可。
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 int a[40][40]; 4 int dx[4]={1,-1,0,0}; 5 int dy[4]={0,0,1,-1}; 6 bool book[40][40]; 7 struct node 8 { 9 int x,y; 10 }; 11 queue<node>q; 12 int num=1; 13 int ha,la; 14 int n,m; 15 void bfs() 16 { 17 node s; 18 s.x=ha; 19 s.y=la; 20 q.push(s); 21 while(!q.empty()) 22 { 23 node p=q.front(); 24 node v; 25 for (int i = 0; i < 4; ++i) 26 { 27 v.x=p.x+dx[i]; 28 v.y=p.y+dy[i]; 29 if (v.x>=1&&v.x<=m&&v.y>=1&&v.y<=n&&book[v.x][v.y]==0&&a[v.x][v.y]!=0) 30 { 31 //cout<<"111"<<endl; 32 book[v.x][v.y]=1; 33 q.push(v); 34 num++; 35 } 36 } 37 q.pop(); 38 } 39 } 40 int main(int argc, char const *argv[]) 41 { 42 while(1) 43 { 44 cin>>n>>m; 45 if (n+m==0) break; 46 char c; 47 for (int i = 1; i <= m; ++i) 48 { 49 for (int j = 1; j <= n; ++j) 50 { 51 cin>>c; 52 if (c=='.') 53 { 54 a[i][j]=1; 55 } 56 else if (c=='@') 57 { 58 a[i][j]=2; 59 ha=i; 60 la=j; 61 book[ha][la]=1; 62 } 63 else 64 { 65 a[i][j]=0; 66 } 67 } 68 } 69 bfs(); 70 cout<<num<<endl; 71 num=1; 72 memset(a,0,sizeof(a)); 73 memset(book,0,sizeof(book)); 74 } 75 return 0; 76 }
poj3278 题目链接:http://poj.org/problem?id=3278
注意进队条件和判重,不然会MLE
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 int n,k; 5 int book[100055]; 6 struct node 7 { 8 int x,minute; 9 }; 10 queue<node>q; 11 void bfs() 12 { 13 node s; 14 s.x=n; 15 s.minute=0; 16 q.push(s); 17 while(!q.empty()) 18 { 19 node p=q.front(); 20 if(p.x==k) 21 { 22 cout<<p.minute<<endl; 23 return ; 24 } 25 node v; 26 for (int i = 1; i <= 3; ++i) 27 { 28 switch(i) 29 { 30 case 1:v.x=p.x+1;break; 31 case 2:v.x=p.x-1;break; 32 case 3:v.x=p.x*2;break; 33 } 34 if(v.x>=0&&v.x<=100000&&book[v.x]==0) 35 { 36 book[v.x]=1; 37 v.minute=p.minute+1; 38 q.push(v); 39 } 40 } 41 q.pop(); 42 } 43 } 44 int main(int argc, char const *argv[]) 45 { 46 cin>>n>>k; 47 bfs(); 48 return 0; 49 }
poj1426 题目链接 http://poj.org/problem?id=1426
*10入队或*10+1入队
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<stdio.h> 3 #include<queue> 4 using namespace std; 5 void bfs(int t) 6 { 7 queue<long long>q; 8 q.push(1); 9 while(!q.empty()) 10 { 11 long long p=q.front(); 12 q.pop(); 13 if (p%t==0) 14 { 15 printf("%lld ",p); 16 return; 17 } 18 q.push(p*10); 19 q.push(p*10+1); 20 } 21 } 22 int main(int argc, char const *argv[]) 23 { 24 int n; 25 while(cin>>n) 26 { 27 if (n==0) break; 28 bfs(n); 29 } 30 return 0; 31 }
poj3126 题目链接:http://poj.org/problem?id=3126
由于题目限制4位数,遍历4个位置跟换数字判断是否符合要求入队即可
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <queue> 3 #include <algorithm> 4 #include <string.h> 5 #include <math.h> 6 using namespace std; 7 int book[100000]; 8 bool judge_prime(int x) //判断素数 9 { 10 if(x == 0 || x == 1) 11 return false; 12 else if(x == 2 || x == 3) 13 return true; 14 else 15 { 16 for(int i = 2; i <= (int)sqrt(x); i++) 17 if(x % i == 0) 18 return false; 19 return true; 20 } 21 } 22 struct node 23 { 24 int x,step; 25 }; 26 int a[10]={0,1,2,3,4,5,6,7,8,9}; 27 int ax,b; 28 void bfs() 29 { 30 queue<node>q; 31 node s; 32 s.x=ax; 33 s.step=0; 34 q.push(s); 35 book[ax]=1; 36 while(!q.empty()) 37 { 38 node p=q.front(); 39 if (p.x==b) 40 { 41 cout<<p.step<<endl; 42 return; 43 } 44 for (int i = 0; i < 10; ++i) 45 { 46 node v; 47 for (int j = 1; j <= 4; ++j) 48 { 49 switch(j) 50 { 51 case 1:v.x=p.x/10*10+a[i];break; 52 case 2:v.x=(p.x-(p.x/10*10))+(a[i]*10)+(p.x/100*100);break; 53 case 3:v.x=(p.x-(p.x/100*100))+(a[i]*100)+(p.x/1000*1000);break; 54 case 4:v.x=a[i]*1000+(p.x-(p.x/1000*1000));break; 55 } 56 57 v.step=p.step+1; 58 if (judge_prime(v.x)&&book[v.x]==0&&v.x>=1000&&v.x<=9999) 59 { 60 //cout<<"v.x"<<v.x<<endl; 61 book[v.x]=1; 62 q.push(v); 63 } 64 } 65 } 66 q.pop(); 67 } 68 } 69 int main(int argc, char const *argv[]) 70 { 71 int t; 72 cin>>t; 73 while(t--) 74 { 75 cin>>ax>>b; 76 bfs(); 77 memset(book,0,sizeof(book)); 78 } 79 return 0; 80 }
poj 3414 题目链接 https://vjudge.net/problem/15208/origin
考虑6种情况对应0-5的6个数字,入队即可
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <queue> 3 #include <string.h> 4 using namespace std; 5 string cz[6]={"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"}; 6 int a,b,c; 7 int book[1000][1000]; 8 struct node 9 { 10 int xa,xb; 11 string s; 12 }; 13 bool flag=1; 14 void bfs() 15 { 16 queue<node>q; 17 node z; 18 z.xa=0; 19 z.xb=0; 20 q.push(z); 21 while(!q.empty()) 22 { 23 node p=q.front(); 24 if (p.xa==c||p.xb==c) 25 { 26 flag=0; 27 int ans=p.s.length(); 28 cout<<ans<<endl; 29 for (int i = 0; i < ans; ++i) 30 { 31 //cout<<"p.s[i]-'0'"<<p.s[i]-'0'<<endl; 32 cout<<cz[p.s[i]-'0']<<endl; 33 } 34 return ; 35 } 36 else 37 { 38 node zzs; 39 for (int i = 0; i < 6; ++i) 40 { 41 if (i==0&&p.xa!=a) 42 { 43 zzs.xa=a; 44 zzs.xb=p.xb; 45 zzs.s=p.s+'0'; 46 } 47 else if (i==1&&p.xb!=b) 48 { 49 zzs.xa=p.xa; 50 zzs.xb=b; 51 zzs.s=p.s+'1'; 52 } 53 else if (i==2&&p.xa!=0) 54 { 55 zzs.xa=0; 56 zzs.xb=p.xb; 57 zzs.s=p.s+'2'; 58 } 59 else if (i==3&&p.xb!=0) 60 { 61 zzs.xa=p.xa; 62 zzs.xb=0; 63 zzs.s=p.s+'3'; 64 } 65 else if (i==4&&p.xa!=0) 66 { 67 if (p.xa-(b-p.xb)>=0) 68 { 69 zzs.xa=p.xa-(b-p.xb); 70 zzs.xb=b; 71 } 72 else 73 { 74 zzs.xa=0; 75 zzs.xb=p.xa+p.xb; 76 } 77 zzs.s=p.s+'4'; 78 } 79 else if (i==5&&p.xb!=0) 80 { 81 if (p.xb-(a-p.xa)>=0) 82 { 83 zzs.xa=a; 84 zzs.xb=p.xb-(a-p.xa); 85 } 86 else 87 { 88 zzs.xa=p.xa+p.xb; 89 zzs.xb=0; 90 } 91 zzs.s=p.s+'5'; 92 } 93 if (book[zzs.xa][zzs.xb]==0) 94 { 95 book[zzs.xa][zzs.xb]=1; 96 q.push(zzs); 97 } 98 } 99 q.pop(); 100 } 101 } 102 } 103 int main(int argc, char const *argv[]) 104 { 105 while(cin>>a>>b>>c) 106 { 107 bfs(); 108 if (flag) cout<<"impossible"<<endl; 109 flag=1; 110 memset(book,0,sizeof(book)); 111 } 112 113 return 0; 114 }