98. 所有可达路径
深度优先搜索(dfs)和广度优先搜索(bfs)区别:
- dfs是可一个方向去搜,不到黄河不回头,直到遇到绝境了,搜不下去了,再换方向(换方向的过程就涉及到了回溯)。
- bfs是先把本节点所连接的所有节点遍历一遍,走到下一个节点的时候,再把连接节点的所有节点遍历一遍,搜索方向更像是广度,四面八方的搜索过程。
n, m = map(int, input().split())
print(' '.join(map(str, path)))
def dfs(graph, point, n, path, result):
if point == n:
result.append(path[:])
return
for i in range(1, n + 1):
if graph[point][i] == 1:
path.append(i)
dfs(graph, i, n, path, result)
path.pop()
def main():
n, m = map(int, input().split())
graph = [[0]*(n+1) for _ in range(n+1)]
for _ in range(m):
s, t = map(int, input().split())
graph[s][t] = 1
path = [1]
results = []
dfs(graph, 1, n, path, results)
if not results:
print(-1)
else:
for path in results:
print(' '.join(map(str, path)))
if __name__ == "__main__":
main()
99. 岛屿数量
dfs深度优先搜索:
direction = [[0,1],[0,-1],[-1,0],[1,0]]
def dfs(graph, i, j):
for d in direction:
x = i + d[0]
y = j + d[1]
if x >= 0 and x < len(graph) and y >= 0 and y < len(graph[0]) and graph[x][y] == 1:
graph[x][y] = 0
dfs(graph, x, y)
n,m = map(int, input().split())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
result = 0
for i in range(n):
for j in range(m):
if graph[i][j] == 1:
result += 1
dfs(graph, i, j)
graph[i][j] = 0
print(result)
bfs广度优先搜索:
from collections import deque
direction = [[0,1],[0,-1],[-1,0],[1,0]]
def bfs(graph, i, j, visited):
que = deque()
que.append([i,j])
visited[i][j] = True
while que:
cur_x, cur_y = que.popleft()
for d in direction:
next_x = cur_x + d[0]
next_y = cur_y + d[1]
if next_x >= 0 and next_x < len(graph) and next_y >= 0 and next_y < len(graph[0]) and not visited[next_x][next_y] and graph[next_x][next_y] == 1:
que.append([next_x,next_y])
visited[next_x][next_y] = True
n,m = map(int, input().split())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
visited = [[False]*m for _ in range(n)]
result = 0
for i in range(n):
for j in range(m):
if graph[i][j] == 1 and not visited[i][j]:
result += 1
# visited[i][j] = True
bfs(graph, i, j, visited)
print(result)
100. 岛屿的最大面积
bfs
这里注意count不能当成bfs的参数传,因为这样的话只是局部改变bfs内的count,主函数中count不受影响。
from collections import deque
directions = [[0,1],[0,-1],[1,0],[-1,0]]
def bfs(graph, x, y, visited):
que = deque()
que.append([x,y])
visited[x][y] = True
count = 1
while que:
cur_x, cur_y = que.popleft()
for d in directions:
next_x = cur_x + d[0]
next_y = cur_y + d[1]
if next_x >= 0 and next_x < len(graph) and next_y >= 0 and next_y < len(graph[0]) and not visited[next_x][next_y] and graph[next_x][next_y] == 1:
count += 1
visited[next_x][next_y] = True
que.append([next_x,next_y])
return count
n, m = map(int, input().split())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
visited = [[False]*m for _ in range(n)]
result = 0
for i in range(n):
for j in range(m):
if graph[i][j] == 1 and not visited[i][j]:
count = bfs(graph, i, j, visited)
result = max(result, count)
print(result)
dfs:
注意这里,我没有用visited标记遍历过的点,而是直接将遍历过的1变成0,以避免dfs中的递归进入死循环。
directions = [[0,1],[0,-1],[1,0],[-1,0]]
count = 0
def dfs(graph, x, y):
global count
for d in directions:
next_x = x + d[0]
next_y = y + d[1]
if next_x >= 0 and next_x < len(graph) and next_y >= 0 and next_y < len(graph[0]) and graph[next_x][next_y] == 1:
count += 1
graph[next_x][next_y] = 0
dfs(graph, next_x, next_y)
n, m = map(int, input().split())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
result = 0
for i in range(n):
for j in range(m):
if graph[i][j] == 1:
count = 1
graph[i][j] = 0
dfs(graph, i, j)
result = max(result, count)
print(result)
101. 孤岛的总面积
深搜dfs:
# count = 0
directions = [[0,1],[0,-1],[1,0],[-1,0]]
def dfs(graph, x, y):
# global count
# count += 1
graph[x][y] = 0
for d in directions:
next_x = x + d[0]
next_y = y + d[1]
if next_x >= 0 and next_x < len(graph) and next_y>=0 and next_y<len(graph[0]) and graph[next_x][next_y] == 1:
graph[next_x][next_y] = 0
# count += 1
dfs(graph, next_x, next_y)
n, m = map(int, input().split())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
for i in range(n):
if graph[i][0] == 1:
# graph[i][0] = 0
dfs(graph, i, 0)
if graph[i][m-1] == 1:
# graph[i][m-1] = 0
dfs(graph, i, m-1)
for j in range(1, m-1):
if graph[0][j] == 1:
dfs(graph, 0, j)
if graph[n-1][j] == 1:
dfs(graph, n-1, j)
count = 0
for i in range(n):
for j in range(m):
if graph[i][j] == 1:
# dfs(graph, i, j)
count += 1
print(count)
count = 0
directions = [[0,1],[0,-1],[1,0],[-1,0]]
def dfs(graph, x, y):
global count
# 不能在这里加一,因为后面递归之前加了一次,递归的时候进来又加一次就重复了
# count += 1
graph[x][y] = 0
for d in directions:
next_x = x + d[0]
next_y = y + d[1]
if next_x >= 0 and next_x < len(graph) and next_y>=0 and next_y<len(graph[0]) and graph[next_x][next_y] == 1:
graph[next_x][next_y] = 0
count += 1
dfs(graph, next_x, next_y)
n, m = map(int, input().split())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
for i in range(n):
if graph[i][0] == 1:
# graph[i][0] = 0
dfs(graph, i, 0)
if graph[i][m-1] == 1:
# graph[i][m-1] = 0
dfs(graph, i, m-1)
for j in range(1, m-1):
if graph[0][j] == 1:
dfs(graph, 0, j)
if graph[n-1][j] == 1:
dfs(graph, n-1, j)
count = 0
for i in range(n):
for j in range(m):
if graph[i][j] == 1:
count += 1
dfs(graph, i, j)
# count += 1
print(count)
广搜bfs:
from collections import deque
count = 0
directions = [[0,1],[0,-1],[1,0],[-1,0]]
def bfs(graph, x, y):
que = deque()
que.append([x,y])
graph[x][y] = 0
global count
# 不能在这里加一,因为后面递归之前加了一次,递归的时候进来又加一次就重复了
# count += 1
while que:
x, y = que.popleft()
for d in directions:
next_x = x + d[0]
next_y = y + d[1]
if next_x >= 0 and next_x < len(graph) and next_y>=0 and next_y<len(graph[0]) and graph[next_x][next_y] == 1:
graph[next_x][next_y] = 0
count += 1
que.append([next_x,next_y])
n, m = map(int, input().split())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
for i in range(n):
if graph[i][0] == 1:
# graph[i][0] = 0
bfs(graph, i, 0)
if graph[i][m-1] == 1:
# graph[i][m-1] = 0
bfs(graph, i, m-1)
for j in range(1, m-1):
if graph[0][j] == 1:
bfs(graph, 0, j)
if graph[n-1][j] == 1:
bfs(graph, n-1, j)
count = 0
for i in range(n):
for j in range(m):
if graph[i][j] == 1:
count += 1
bfs(graph, i, j)
# count += 1
print(count)
102. 沉没孤岛
dfs深度优先搜索
directions = [[0,1], [0,-1], [1,0], [-1,0]]
n,m = map(int, input().split())
g = []
for _ in range(n):
g.append(list(map(int, input().split())))
def dfs(g, x, y):
g[x][y] = 2
for d in directions:
next_x = x + d[0]
next_y = y + d[1]
if next_x>=0 and next_x<len(g) and next_y>=0 and next_y<len(g[0]) and g[next_x][next_y] == 1:
dfs(g, next_x, next_y)
for i in range(n):
if g[i][0] == 1:
dfs(g, i, 0)
if g[i][m-1] == 1:
dfs(g, i, m-1)
for j in range(1,m-1):
if g[0][j] == 1:
dfs(g, 0, j)
if g[n-1][j] == 1:
dfs(g, n-1, j)
for i in range(n):
for j in range(m):
if g[i][j] > 0:
g[i][j] -= 1
for i in range(n):
print(" ".join(map(str, g[i])))
bfs广度优先搜索
from collections import deque
directions = [[0,1], [0,-1], [1,0], [-1,0]]
n,m = map(int, input().split())
g = []
for _ in range(n):
g.append(list(map(int, input().split())))
def dfs(g, x, y):
que = deque()
que.append([x,y])
g[x][y] = 2
while que:
x, y = que.popleft()
for d in directions:
next_x = x + d[0]
next_y = y + d[1]
if next_x>=0 and next_x<len(g) and next_y>=0 and next_y<len(g[0]) and g[next_x][next_y] == 1:
g[next_x][next_y] = 2
que.append([next_x, next_y])
for i in range(n):
if g[i][0] == 1:
dfs(g, i, 0)
if g[i][m-1] == 1:
dfs(g, i, m-1)
for j in range(1,m-1):
if g[0][j] == 1:
dfs(g, 0, j)
if g[n-1][j] == 1:
dfs(g, n-1, j)
for i in range(n):
for j in range(m):
if g[i][j] > 0:
g[i][j] -= 1
for i in range(n):
print(" ".join(map(str, g[i])))