1. 定义 树的BFS:从根节点开始,从左到右,从上到下进行的层次遍历;
图的BFS:从根节点出发,找与该结点相邻的所有结点,如此类推,一层层遍历。
图没有根结点,就得找一个点作为根节点。例如是A,则找与A相连距离1条边的结点,有B、C;再找与A距离2条边的结点有D、E;最后与A距离为3的结点有F。故BFS的遍历顺序为:ABCDEF
注意,取的点不同,有不同的遍历结果。例如遍历A结点之后,遍历B、C,则第三层要把与B相连的所有邻接点遍历完,即是ABCDE,而不能是ABCED,因为E结点和B没有直接相连。
另外一种遍历方式也可以是:ACBEDF 。
2. BFS用队列保证层的顺序
队列是先进先出的特点,把BFS遍历的结点从队尾开始进入,再从队头出来。每出队一个元素,则把该元素的所有邻接点入队,以保证层的顺序。
例如先把A结点入队,A出队的时候把A所有邻接点入队,即B、C,由于B在C的前面,B的邻接点要比C的邻接点先出现,故把D塞进来,再到E。如此类推。(保证了先进来的B、C离A比较近,后进来的离A较远)
3.例题
给出一个二维数组,每次只能走该点的上下左右,且每次只能走从高到低的点,没走过一个点距离+1。问走的最大距离是多少。
5 4 1 2 3 4 16 17 18 5 15 29 25 6 14 11 22 7 23 10 9 8
输出最大距离为18
25->18->17->16->15->14->11->10->9->8->7->6->5->4->3->2->1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 #include <iostream> #include <cstring> using namespace std;const int maxn = 1e2 + 10 ;int Map[maxn][maxn];int dp[maxn][maxn];int row,col;int check (int i,int j) { return (i >= 1 && j >= 1 && i <= row && j <= col); } int BFS (int i,int j) { int Max = 0 ; if (check (i,j+1 ) && Map[i][j] > Map[i][j+1 ]) { if (dp[i][j+1 ]) Max = Max > dp[i][j+1 ] ? Max : dp[i][j+1 ]; else Max = Max > BFS (i,j+1 ) ? Max : BFS (i,j+1 ); } if (check (i+1 ,j) && Map[i][j] > Map[i+1 ][j]) { if (dp[i+1 ][j]) Max = Max > dp[i+1 ][j] ? Max : dp[i+1 ][j]; else Max = Max > BFS (i+1 ,j) ? Max : BFS (i+1 ,j); } if (check (i,j-1 ) && Map[i][j] > Map[i][j-1 ]) { if (dp[i][j-1 ]) Max = Max > dp[i][j-1 ] ? Max : dp[i][j-1 ]; else Max = Max > BFS (i,j-1 ) ? Max : BFS (i,j-1 ); } if (check (i-1 ,j) && Map[i][j] > Map[i-1 ][j]) { if (dp[i-1 ][j]) Max = Max > dp[i-1 ][j] ? Max : dp[i-1 ][j]; else Max = Max > Map[i-1 ][j] ? Max : BFS (i-1 ,j); } if (Max == 0 ) dp[i][j] = 1 ; else dp[i][j] = Max + 1 ; return dp[i][j]; } int main () { while (cin >> row >> col) { memset (dp,0 ,sizeof (dp)); for (int i = 1 ; i<=row; i++) for (int j = 1 ; j<=col; j++) cin >> Map[i][j]; int ans = 0 ; for (int i=1 ;i<=row;i++) { for (int j=1 ;j<=col;j++) { int tmp = BFS (i,j); if (tmp > ans) ans = tmp; } } cout << ans <<endl; } return 0 ; }
LeetCode 腐烂的橘子
在给定的网格中,每个单元格可以有以下三个值之一:
值 0 代表空单元格; 值 1 代表新鲜橘子; 值 2 代表腐烂的橘子。 每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。
返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1。
代码中~dis[tx][ty]
是位运算中的取反,二维数组dis开始初始化为-1,-1取反为0,此处就是判断dis[tx][ty]
是否为0,根据题意,0就是没有橘子的地方,不作处理。
队列用来存放腐烂橘子的坐标,能把该坐标上下左右新鲜的橘子变腐烂。
make_pair(i,j) 无需写类型就能生成pair对象,可以直接放入队列中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 int orangesRotting (vector<vector<int >>& grid) { int cnt = 0 ,ans = 0 ; int dis[10 ][10 ]; int dir_x[4 ] = {1 ,0 ,-1 ,0 }; int dir_y[4 ] = {0 ,-1 ,0 ,1 }; queue<pair<int ,int >> q; memset (dis,-1 ,sizeof (dis)); int n = grid.size (), m = grid[0 ].size (); for (int i = 0 ; i < n; i++){ for (int j = 0 ; j < m; j++){ if (grid[i][j] == 2 ){ q.push (make_pair (i,j)); dis[i][j] = 0 ; } else if (grid[i][j] == 1 ) cnt++; } } while (!q.empty ()){ pair<int ,int > x = q.front (); q.pop (); for (int i = 0 ; i < 4 ; i++){ int tx = x.first + dir_x[i]; int ty = x.second + dir_y[i]; if (tx < 0 || tx >= n || ty < 0 || ty >= m || ~dis[tx][ty] || !grid[tx][ty]) continue ; dis[tx][ty] = dis[x.first][x.second] + 1 ; q.push (make_pair (tx,ty)); if (grid[tx][ty] == 1 ) { cnt--; ans = dis[tx][ty]; if (!cnt) break ; } } } return cnt ? -1 : ans; }
LeetCode 地图分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 int maxDistance (vector<vector<int >>& grid) { int dir_x[4 ] = {0 ,1 ,0 ,-1 }; int dir_y[4 ] = {1 ,0 ,-1 ,0 }; queue<pair<int ,int >>q; int n = grid.size (); int m = grid[0 ].size (); for (int i = 0 ; i < n; i++){ for (int j = 0 ; j < m; j++){ if (grid[i][j] == 1 ){ q.push (make_pair (i,j)); } } } if (q.empty () || q.size () == n*m) return -1 ; pair<int ,int >x; while (!q.empty ()){ x = q.front (); q.pop (); for (int i = 0 ; i < 4 ; i++){ int tx = x.first + dir_x[i]; int ty = x.second + dir_y[i]; if (tx < 0 || tx >= n || ty < 0 || ty >= m || grid[tx][ty] != 0 ) continue ; grid[tx][ty] = grid[x.first][x.second] + 1 ; q.push (make_pair (tx,ty)); } } return grid[x.first][x.second] - 1 ; }