zoukankan      html  css  js  c++  java
  • 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 }

  • 相关阅读:
    kendo ui 查找treelist里的子控件并设置是否显示的方法
    KendoUi下的DatePicker在谷歌浏览器上不能正常显示时间的解决方法
    asp.net 第三方UI控件 Telerik KendoUI 之 TreeVIew 的用法记录
    mysql批量更新数据,即:循环select记录然后更新某一字段
    Sql语句备份Sqlserver数据库
    3des用法示例,已测试
    制作Windows服务项目详细攻略
    利用好压在C#程序里实现RAR格式的压缩和解压功能
    winform里textBox无法获得焦点的解决方案
    Shell脚本批量重命名案例
  • 原文地址:https://www.cnblogs.com/waryan/p/12182268.html
Copyright © 2011-2022 走看看