一般来说,广搜常用于找单一的最短路线,或者是规模小的路径搜索,它的特点是"搜到就是最优解", 而深搜用于找多个解或者是"步数已知(比如3步就必须达到条件)"的问题,它的空间效率高,但是找到的不一定是最优解,必须记录并完成整个搜索,故一般情况下,深搜需要非常高效的剪枝(优化).
像搜索最短路径这些的很明显要是用广搜,因为广搜的特性就是一层一层往下搜的,保证当前搜到的都是最优解,当然,最短路径只是一方面的应用,像什么最少状态转换也是可以应用的。
深搜就是优先搜索一棵子树,然后是另一棵,它和广搜相比,有着内存需要相对较少的优点,八皇后问题就是典型的应用,这类问题很明显是不能用广搜去解决的。或者像图论里面的找圈的算法,数的前序中序后序遍历等,都是深搜。
深搜和广搜的不同之处是在于搜索顺序的不同。
深搜的实现类似于栈,每次选择栈顶元素去扩展,
广搜则是利用了队列,先被扩展的的节点优先拿去扩展。
搜索树的形态:深搜层数很多,广搜则是很宽。
深搜适合找出所有方案,广搜则用来找出最佳方案
深搜和广搜的区别:
深搜并不能保证第一次遇到目标点就是最短路径,因此要搜索所有可能的路径,因此要回溯,标记做了之后还要取消掉,因此同一个点可能被访问很多很多次。而广搜由于它的由近及远的结点扩展顺序,结点总是以最短路径被访问。一个结点如果第二次被访问,第二次的路径肯定不会比第一次的短,因此就没有必要再从这个结点向周围扩展――第一次访问这个结点的时候已经扩展过了,第二次再扩展只会得到更差的解。因此做过的标记不必去掉。因此同一个点至多只可能被访问一次。每访问一个结点,与它相连的边就被检查一次。因此最坏情况下,所有边都被检查一次,因此时间复杂度为O(E)。
BFS:
1 #include<stdio.h> 2 #include<ctype.h> 3 #include<queue> 4 #include<stack> 5 #include<limits.h> 6 #include<string.h> 7 #include<iostream> 8 using namespace std; 9 int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; 10 int n,m; 11 struct node 12 { 13 int time; 14 int x,y; 15 int prex,prey; 16 char data; 17 bool operator<(const node&a)const 18 { 19 return a.time<time; 20 } 21 }s[105][105]; 22 typedef struct t 23 { 24 int x,y; 25 }T; 26 node cur1;T cur2,next2; 27 int BFS() 28 { 29 priority_queue<node>qu; 30 int i,x1,y1; 31 s[0][0].time=0; 32 qu.push(s[0][0]); 33 while(!qu.empty()) 34 { 35 cur1=qu.top(); 36 qu.pop(); 37 if(cur1.x==n-1 && cur1.y==m-1) 38 return 1; 39 for(i=0;i<4;i++) 40 { 41 x1=cur1.x+dir[i][0]; 42 y1=cur1.y+dir[i][1]; 43 if(x1>=0 && x1<n && y1>=0 && y1<m) 44 { 45 if(s[x1][y1].data==‘.‘&& s[x1][y1].time>cur1.time+1) 46 { 47 y1]); s[x1][y1].time=cur1.time+1; 48 s[x1][y1].prex=cur1.x; 49 s[x1][y1].prey=cur1.y; 50 qu.push(s[x1][ 51 } 52 else if(isdigit(s[x1][y1].data)&& s[x1][y1].time>cur1.time+s[x1][y1].data-‘0‘) 53 { 54 s[x1][y1].time=cur1.time+s[x1][y1].data-‘0‘+1; 55 s[x1][y1].prex=cur1.x; 56 s[x1][y1].prey=cur1.y; 57 qu.push(s[x1][y1]); 58 } 59 } 60 } 61 } 62 return 0; 63 } 64 void printpath(int x,int y) 65 { 66 if(x==0&&y==0)return ; 67 68 int prex=s[x][y].prex; 69 int prey=s[x][y].prey; 70 printpath(prex,prey); 71 int prelength=s[prex][prey].time; 72 int length=s[x][y].time; 73 printf("%ds:(%d,%d)->(%d,%d)\n",prelength+1,prex,prey,x,y); 74 for(int i=prelength+2;i<=length;i++) 75 { 76 printf("%ds:FIGHT AT (%d,%d)\n",i,x,y); 77 } 78 } 79 int main() 80 { 81 setbuf(stdout,NULL); 82 int i,j; 83 while(scanf("%d %d",&n,&m)!=EOF) 84 { 85 for(i=0;i<n;i++) 86 { 87 for(j=0;j<m;j++) 88 { 89 cin>>s[i][j].data; 90 s[i][j].x=i; 91 s[i][j].y=j; 92 s[i][j].time=INT_MAX; 93 } 94 } 95 int state=BFS(); 96 if(!state) 97 { 98 printf("God please help our poor hero.\n"); 99 printf("FINISH\n"); 100 continue; 101 } 102 printf("It takes %d seconds to reach the target position, let me show you the way.\n",s[n-1][m-1].time); 103 printpath(n-1,m-1); 104 printf("FINISH\n"); 105 } 106 return 0; 107 }
DFS:超时但是节约空间。
1 #include<iostream> 2 #include<stdio.h> 3 #include<limits.h> 4 #include<string.h> 5 #include<cstdlib> 6 using namespace std; 7 int N,M,OK; 8 char map[105][105]; 9 int X[4]={1,-1,0,0}; 10 int Y[4]={0,0,1,-1}; 11 struct node 12 { 13 int prex; 14 int prey; 15 int length; 16 }; 17 node visited[105][105]; 18 void DFS(int x,int y,int prelength) 19 { 20 visited[x][y].length=prelength; 21 if(x==N-1&&y==M-1) 22 { 23 OK=1; 24 return ; 25 } 26 for(int i=0;i<4;i++) 27 { 28 int newx=x+X[i]; 29 int newy=y+Y[i]; 30 if(newx>=0&&newx<N&&newy>=0&&newy<M&&map[newx][newy]!=‘X‘) 31 { 32 if(map[newx][newy]==‘.‘&&(prelength+1<visited[newx][newy].length)) 33 { 34 visited[newx][newy].prex=x; 35 visited[newx][newy].prey=y; 36 DFS(newx,newy,prelength+1); 37 }else 38 if(map[newx][newy]>‘0‘&& map[newx][newy]<=‘9‘) 39 { 40 int stay=map[newx][newy]-‘0‘; 41 if(prelength+stay+1<visited[newx][newy].length) 42 { 43 visited[newx][newy].prex=x; 44 visited[newx][newy].prey=y; 45 DFS(newx,newy,prelength+stay+1); 46 } 47 } 48 } 49 } 50 } 51 void printpath(int x,int y) 52 { 53 if(x==0&&y==0)return ; 54 55 int prex=visited[x][y].prex; 56 int prey=visited[x][y].prey; 57 printpath(prex,prey); 58 int prelength=visited[prex][prey].length; 59 int length=visited[x][y].length; 60 printf("%ds:(%d,%d)->(%d,%d)\n",prelength+1,prex,prey,x,y); 61 for(int i=prelength+2;i<=length;i++) 62 { 63 printf("%ds:FIGHT AT (%d,%d)\n",i,x,y); 64 } 65 66 } 67 int main() 68 { 69 int i,j; 70 while(scanf("%d %d",&N,&M)!=EOF) 71 { 72 OK=0; 73 for(i=0;i<N;i++) 74 { 75 getchar(); 76 for(j=0;j<M;j++) 77 { 78 //cin>>map[i][j] 79 scanf("%c",&map[i][j]); 80 visited[i][j].prex=-1; 81 visited[i][j].prey=-1; 82 visited[i][j].length=INT_MAX; 83 } 84 } 85 DFS(0,0,0); 86 if(!OK) 87 { 88 printf("God please help our poor hero.\n"); 89 printf("FINISH\n"); 90 continue; 91 } 92 printf("It takes %d seconds to reach the target position, let me show you the way.\n",visited[N-1][M-1].length); 93 printpath(N-1,M-1); 94 printf("FINISH\n"); 95 } 96 return 0; 97 }
时间: 2024-10-13 14:50:23