DFS和BFS

DFS :  acwing 842 递归搜索树 题库 - AcWing

 

复制代码
 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int N = 10;
 5 int n;
 6 int path[N];
 7 bool st[N];
 8 
 9 void dfs(int u)
10 {
11     if(u == n) //一个分支走到头
12     {
13         for (int i = 0; i < n; i ++ ) printf("%d ",path[i]); //分别输出分支的每一个数
14         cout << endl;
15         return ; //返回上一层
16     }
17     
18     for (int i = 1; i <= n; i ++ ) //空位上可选择的数字为 1 ~ n;
19     {
20         if(!st[i]) //如果数字i没有被用过
21         {
22             path[u] = i;   //这个数填入空位 按顺序
23             st[i] = true;  //数字被用,修改状态
24             dfs(u + 1);    //填下一个位置
25             st[i] = false;  //回溯,取出i
26         }
27     }
28 }
29 
30 int main()
31 {
32     cin >> n;
33 
34     dfs(0);
35     
36     return 0;
37 }
View Code
复制代码

 

 

 

 

例题:acwing 843 皇后问题  题库 - AcWing

1.

复制代码
 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int N = 20;
 5 int n;
 6 char g[N][N];
 7 bool col[N],dg[N],udg[N];
 8 
 9 void dfs(int u)
10 {
11     if(u == n) //一个分支走到头
12     {
13         for (int i = 0; i < n; i ++ ) puts(g[i]); //分别输出分支的每一个数
14         cout << endl;
15         return; //返回上一层
16     }
17     
18     for (int i = 0; i < n; i ++ ) //空位上可选择的数字为 1 ~ n;
19     {
20         if(!col[i] && !dg[u + i] && !udg[n - u + i]) //如果数字i没有被用过
21         {
22             g[u][i] = 'Q';   //这个数填入空位 按顺序
23             col[i] = dg[u + i] = udg[n- u + i] = true;  //数字被用,修改状态
24             dfs(u + 1);    //填下一个位置
25             col[i] = dg[u + i] = udg[n- u + i] = false; //回溯,取出i
26             g[u][i] = '.';
27         }
28     }
29 }
30 
31 int main()
32 {
33     cin >> n;
34     for (int i = 0; i < n; i ++ )
35        for (int j = 0; j < n; j ++ )
36          g[i][j] = '.';
37 
38     dfs(0);
39     
40     return 0;
41 }
View Code
复制代码

2.(更加原始的方法)

复制代码
 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int N = 20;
 5 int n;
 6 char g[N][N];
 7 bool row[N],col[N],dg[N],udg[N];
 8 
 9 void dfs(int x,int y,int s)
10 {
11     if(y == n) y = 0, x ++;
12     
13     if(x == n)
14     {
15         if(s == n)
16         {
17             for (int i = 0; i < n; i ++ ) puts(g[i]);
18             cout << endl;
19         }
20         return ;
21     }
22     
23     // 不放皇后
24     dfs(x,y + 1,s);
25     
26     //放皇后
27     if(!row[x] && !col[y] && !dg[x + y] && !udg[x - y +n])
28     {
29         g[x][y] = 'Q';
30         row[x] = col[y] = dg[x + y] = udg[x - y + n] = true;
31         dfs(x,y + 1,s + 1);
32         row[x] = col[y] = dg[x + y] = udg[x - y + n] = false;
33         g[x][y] = '.';
34     }
35 
36 }
37 
38 int main()
39 {
40     cin >> n;
41     for (int i = 0; i < n; i ++ )
42        for (int j = 0; j < n; j ++ )
43          g[i][j] = '.';
44 
45     dfs(0,0,0);
46     
47     return 0;
48 }
View Code
复制代码

 

 3.D - Even Relation (atcoder.jp)

通过图论来用邻接表进行搜索,并且搜索一步进行标记并且染色

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 2e5 + 10;
 5 
 6 int n;
 7 int cnt = 1;
 8 
 9 struct op
10 {
11     int from,to,sum;
12 }a[N];
13 
14 int head[N];
15 int ans[N];
16 bool st[N];
17 
18 void hb(int x,int y,int sum)
19 {
20     a[cnt].from = head[x];
21     a[cnt].to = y;
22     a[cnt].sum = sum;
23     head[x] = cnt ++;
24 }
25 
26 void dfs(int x)
27 {
28     for (int i = head[x]; i != 0; i  = a[i].from ) //遍历邻接点
29     {
30         int y = a[i].to; //求出邻接点
31         if(st[y] == 1) continue;
32         if(a[i].sum % 2 == 0)
33         {
34             st[y] = 1; //标记
35             ans[y] = ans[x]; //设为相同
36             dfs(y);
37         }
38         else {
39             st[y] = 1;
40             if(ans[x] == 1) ans[y] = 0;
41             else ans[y] = 1;
42             dfs(y);
43         }
44         
45     }
46 }
47 
48 int main()
49 {
50     cin >> n;
51     int x,y,z;
52     for (int i = 1; i <= n; i ++ )
53     {
54         scanf("%d%d%d", &x, &y, &z);
55         hb(x,y,z); //合并x到y
56         hb(y,x,z); //合并y到x
57     }
58     ans[1] = 1; //把第一个点的颜色设为1
59     st[1] = 1; //标记已经遍历过了
60     dfs(1); //开始遍历
61     for (int i = 1; i <= n; i ++ ) cout << ans[i] << endl;
62     return 0;
63 }
Code
复制代码

 

 

BFS:

走迷宫问题 题库 - AcWing

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 110;
 5 typedef pair<int, int> PII;
 6 
 7 int n,m;
 8 int g[N][N]; //打印地图
 9 int d[N][N]; //存每一个点到起点的距离
10 PII q[N * N]; //手写队列
11 
12 int bfs()
13 {
14    int hh = 0, tt = 0;
15    q[0] = {0,0};
16    memset(d, -1 ,sizeof d); //初始化距离为 -1 表示没有走过
17    d[0][0] = 0; //表示起点走过了
18    
19    int dx[4] = {-1, 0, 1 ,0}, dy[4] = {0,1 , 0, -1}; //表示一个点的四个方向向量
20    
21    while(hh <= tt) // 队列不为空
22    {
23        auto t = q[hh ++]; // 取队头元素
24        for (int i = 0; i < 4; i ++ ) // 枚举四个方向
25        {
26            int x = t.first + dx[i],y = t.second + dy[i];
27            
28            if(x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1)//在边界内且是空地且没有走过
29            {
30                d[x][y] = d[t.first][t.second] + 1; //到起点距离
31                q[ ++ tt] = {x,y}; // 新坐标入队
32                
33             }
34           }
35        }
36        return d[n -1][m - 1]; // 输出右下角距起点的距离即可
37 }
38 
39 int main()
40 {
41     cin >> n >> m;
42     
43     for (int i = 0; i < n; i ++ )
44        for (int j = 0; j < m; j ++ )
45           cin >> g[i][j];
46 
47     cout << bfs() << endl;
48     
49     return 0;
50 }
View Code
复制代码

 例题:P1746 离开中山路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 struct Pos
 5 {
 6     int x,y;
 7 };
 8 queue <Pos> q;  //定义结构体表示x,y两个点的坐标
 9 
10 int dis[1001][1001]; //表示某点到起点的距离
11 int n,x,y,a,b,c,d,tx,ty; //表示起点和终点,以及中途某点的坐标
12 const int dx[4] = {1,-1,0,0}; //表示横纵坐标的偏移量
13 const int dy[4] = {0,0,1,-1};
14 char mp[1001][1001]; //表示地图
15 bool vis[1001][1001]; //表示某个点是否已经走过,如果走过则对其进行标记
16 
17 int bfs(int sx,int sy)
18 {
19     q.push({sx,sy});
20     vis[sx][sy] = true;
21     while(!q.empty())//当输出到最后一个时则会删除完队列中的所有元素,则表示为没有输出完
22     {
23         x = q.front().x;
24         y = q.front().y;
25        
26         q.pop();
27         if(x == c&&y == d) return dis[x][y];
28 
29         for (int i = 0; i < 4; i ++ )
30         {
31             tx = x + dx[i];
32             ty = y + dy[i];
33             if(tx < 0||tx > n || ty < 0 || ty > n) continue; //越界则跳过该点
34                      //  cout<<x<<' '<<y<<endl;
35             if(mp[tx][ty] == '1'||vis[tx][ty] == true) continue; //地图上遇到墙了或者这个点已经走过了
36      
37             dis[tx][ty] = dis[x][y] + 1; //遍历的距离 + 1
38             vis[tx][ty] = true; //标记当前的点已经走过了
39             q.push({tx,ty});
40             
41         }
42              
43     }
44     return -1;
45 }
46 
47 
48 
49 int main()
50 {
51     cin >> n;
52     for (int i = 1; i <= n; i ++ )
53        for (int j = 1; j <= n; j ++ )
54             cin >> mp[i][j];
55             
56             
57     cin >> a >> b >> c >> d;
58     
59     cout << bfs(a,b);
60     return 0;
61 }
Code
复制代码

 

posted @   rw156  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示