DFS和BFS

1.油田连通块

链接地址:地址

递归DFS

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 char map[110][110];
 7 bool vis[110][110]={0};//布尔类型减少内存浪费
 8 int orient[8][2]={1,1,1,0,1,-1,0,1,0,-1,-1,1,-1,0,-1,-1};
 9 //八个方向的遍历
10 int m,n;
11 
12 void DFS(int x,int y)
13 {
14     if(x<0||x>=m||y<0||y>=n)
15         return ;
16     if(vis[x][y]==1||map[x][y]!='@')
17         return ;
18     vis[x][y]=1;
19 
20     for(int i=0;i<8;i++)
21     {
22         DFS(x+orient[i][0],y+orient[i][1]);
23     }
24 }
25 
26 int main()
27 {
28     while(scanf("%d%d",&m,&n)&&m!=0)
29     {
30         memset(vis,0,sizeof(vis));
31         int count=0;
32         for(int i=0;i<m;i++)
33             scanf("%s",map[i]);
34         for(int i=0;i<m;i++)
35             for(int j=0;j<n;j++)
36         {
37             if(vis[i][j]==0&&map[i][j]=='@')
38             {
39                 DFS(i,j);
40                 count++;//计数器
41             }
42         }
43         printf("%d
",count);//不用cout没有追求代码速度,而是追求运行速度
44     }
45     return 0;
46 }

2.Knight Moves

链接地址:链接

单向BFS

a.有返回值类型

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <queue>
 6 using namespace std;
 7 //单向BFS实现,注意队列的使用
 8 bool vis[310][310]={0};
 9 int orient[8][2]={{1,2},{2,1},{-2,1},{-1,2},{-2,-1},{-1,-2},{1,-2},{2,-1}};
10 int l;
11 typedef struct node
12 {
13     int x,y,step;
14 }node;
15 
16 bool check(int x,int y)
17 {
18     if(x<0||x>=l||y<0||y>=l)
19         return false;
20     return true;
21 
22 }
23 int BFS(int x1,int y1,int x2,int y2)
24 {
25     queue<node>Q;//注意队列的清空
26     node temp;
27     temp.x=x1,temp.y=y1,temp.step=0;
28     Q.push(temp);
29     vis[x1][y1]=1;
30     while(!Q.empty())
31     {
32         temp=Q.front();
33         Q.pop();
34         if(temp.x==x2&&temp.y==y2)//判断弹出条件
35             return temp.step;
36         for(int i=0;i<8;i++)
37         {
38             node Next;
39             Next.x=temp.x+orient[i][0];
40             Next.y=temp.y+orient[i][1];
41             Next.step=temp.step+1;
42             if(check(Next.x,Next.y)&&vis[Next.x][Next.y]==0)
43             {
44 
45                 vis[Next.x][Next.y]=1;
46                 Q.push(Next);
47 
48             }
49         }
50     }
51     return 0;//欺骗函数的返回,摆设
52 }
53 int main()
54 {
55     int t,x1,y1,x2,y2;
56     cin>>t;
57     while(t--)
58     {
59         cin>>l;
60         cin>>x1>>y1>>x2>>y2;
61         memset(vis,0,sizeof(vis));
62         printf("%d
",BFS(x1,y1,x2,y2));
63 
64 
65     }
66     return 0;
67 }

b.无返回值类型

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <queue>
 6 using namespace std;
 7 
 8 bool vis[310][310]={0};
 9 int orient[8][2]={{1,2},{2,1},{-2,1},{-1,2},{-2,-1},{-1,-2},{1,-2},{2,-1}};
10 int l;
11 typedef struct node
12 {
13     int x,y,step;
14 }node;
15 
16 bool check(int x,int y)
17 {
18     if(x<0||x>=l||y<0||y>=l)
19         return false;
20     return true;
21 
22 }
23 void BFS(int x1,int y1,int x2,int y2)
24 {
25     queue<node>Q;
26     node temp;
27     temp.x=x1,temp.y=y1,temp.step=0;
28     Q.push(temp);
29     vis[x1][y1]=1;
30     while(!Q.empty())
31     {
32         temp=Q.front();
33         Q.pop();
34         if(temp.x==x2&&temp.y==y2)
35         {
36             printf("%d
",temp.step);//直接进行输出会节省时间
37         }
38         for(int i=0;i<8;i++)
39         {
40             node Next;
41             Next.x=temp.x+orient[i][0];
42             Next.y=temp.y+orient[i][1];
43             Next.step=temp.step+1;
44             if(check(Next.x,Next.y)&&vis[Next.x][Next.y]==0)
45             {
46 
47                 vis[Next.x][Next.y]=1;
48                 Q.push(Next);
49 
50             }
51         }
52     }
53     //return 0;
54 }
55 int main()
56 {
57     int t,x1,y1,x2,y2;
58     cin>>t;
59     while(t--)
60     {
61         cin>>l;
62         cin>>x1>>y1>>x2>>y2;
63         memset(vis,0,sizeof(vis));
64         BFS(x1,y1,x2,y2);
65     }
66     return 0;
67 }

双向BFS

 1 #include <iostream>
 2 #include<algorithm>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <queue>
 7 using namespace std;
 8 const int N = 310;
 9 int l;
10 int vis[N][N];
11 int dis[N][N];
12 int orient[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-2,1},{-2,-1},{-1,2},{-1,-2}};
13 typedef struct node
14 {
15     int x,y;
16 }node;
17 void dBFS(int x1,int y1,int x2,int y2)
18 {
19     if(x1==x2&&y1==y2)//注意相等条件的弹出
20     {
21         printf("0
");
22         return ;
23     }
24     queue<node>Q;
25     node front,behind;//用front,behind是为了复习的时候好理解
26     front.x=x1,front.y=y1;
27     behind.x=x2,behind.y=y2;
28     vis[x1][y1]=1;//从头开始的标记1
29     vis[x2][y2]=2;//从尾开始的标记2
30     Q.push(front);
31     Q.push(behind);
32     while(!Q.empty())
33     {
34         front=Q.front();
35         Q.pop();//注意每次的弹出
36 
37         for(int i=0;i<8;i++)
38         {
39             behind.x=front.x+orient[i][0];
40             behind.y=front.y+orient[i][1];
41             if(behind.x>=0&&behind.x<l&&behind.y>=0&&behind.y<l)//当吧判断条件写成这样可以减少
42             {                                                  //进入函数所浪费的时间
43                 if(!vis[behind.x][behind.y])
44                 {
45                     vis[behind.x][behind.y]=vis[front.x][front.y];
46                     dis[behind.x][behind.y]=dis[front.x][front.y]+1;//距离加1,因为队列是
47                     Q.push(behind);                                 //先进先出所以是BFS
48                 }
49                 else if(vis[behind.x][behind.y]!=vis[front.x][front.y])//最短路径优先输出
50                 {
51                     printf("%d
",dis[front.x][front.y]+dis[behind.x][behind.y]+1);//相遇时少了一步
52                     return;
53                 }
54             }
55         }
56     }
57 }
58 int main()
59 {
60     int t;
61     scanf("%d",&t);
62     while(t--)
63     {
64         memset(vis,0,sizeof(vis));
65         memset(dis,0,sizeof(dis));
66         int x1,y1,x2,y2;
67         scanf("%d%d%d%d%d",&l,&x1,&y1,&x2,&y2);
68         dBFS(x1,y1,x2,y2);
69 
70     }
71     return 0;
72 
73 }

3.Red and Black

求定点连通块,直接DFS

链接

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 char map[30][30];
 7 bool vis[30][30];
 8 int w,h,step;
 9 int orient[4][2]={1,0,0,1,-1,0,0,-1};
10 struct position
11 {
12     int x,y;
13 };
14 
15 void DFS(int x,int y)
16 {
17     if(x<0||x>=h||y<0||y>=w||map[x][y]=='#')
18         return ;
19     if(vis[x][y]!=0)//发现不能用非,一个符号卡了我半小时
20         return;
21     vis[x][y]=1;
22     step=step+1;//计数器
23     for(int i=0;i<4;i++)
24         {
25             DFS(x+orient[i][0],y+orient[i][1]);
26 
27         }
28 }
29 int main()
30 {
31     while(~scanf("%d%d",&w,&h)&&(w*h)!=0)
32     {
33         step=0;
34         position person;
35         memset(map,0,sizeof(map));
36         memset(vis,0,sizeof(vis));
37         for(int i=0;i<h;i++)
38         {
39             getchar();//吸掉每次换行的回车,包括第一次输入w,h
40             for(int j=0;j<w;j++)
41         {
42             scanf("%c",&map[i][j]);
43             if(map[i][j]=='@')
44             {
45                 person.y=i,person.x=j;//记录人的位置
46                 //vis[i][j]=1;
47             }
48         }
49         }
50         DFS(person.y,person.x);
51         printf("%d
",step);
52 
53     }
54     return 0;
55 }

原文地址:https://www.cnblogs.com/waryan/p/12182268.html