851 字
4 分钟
代码随想录算法训练营第四十五天 | 图论 Part03
卡码网:101. 孤岛的总面积
import syssys.setrecursionlimit(10**7)input = sys.stdin.read
def main(): data = input().split() n, m = int(data[0]), int(data[1]) index = 2 graph = [[0] * m for _ in range(n)] for i in range(n): for j in range(m): graph[i][j] = int(data[index]) index += 1 visited = [[False] * m for _ in range(n)]
def dfs(x, y): if x < 0 or x >= n or y < 0 or y >= m: return 0, True if graph[x][y] == 0 or visited[x][y]: return 0, False visited[x][y] = True area = 1 touches_edge = False
for nx, ny in [(x-1,y), (x+1,y), (x,y-1), (x,y+1)]: sub_area, sub_touch = dfs(nx, ny) area += sub_area if sub_touch: touches_edge = True
if x == 0 or x == n-1 or y == 0 or y == m-1: touches_edge = True
return area, touches_edge
total_area = 0 for i in range(n): for j in range(m): if graph[i][j] == 1 and not visited[i][j]: area, touches_edge = dfs(i, j) if not touches_edge: total_area += area
print(total_area)
main()
卡码网:102. 沉没孤岛
import sysinput = sys.stdin.readsys.setrecursionlimit(10**7)
def main(): data = input().split() n, m = int(data[0]), int(data[1]) index = 2 graph = [[0] * m for _ in range(n)] for i in range(n): for j in range(m): graph[i][j] = int(data[index]) index += 1
visited = [[False] * m for _ in range(n)]
def dfs(x, y): if x < 0 or x >= n or y < 0 or y >= m: return if graph[x][y] == 0 or visited[x][y]: return visited[x][y] = True dfs(x - 1, y) dfs(x + 1, y) dfs(x, y - 1) dfs(x, y + 1)
# 从边缘陆地开始,标记所有连通陆地为非孤岛 for i in range(n): for j in range(m): if (i == 0 or j == 0 or i == n - 1 or j == m - 1) and graph[i][j] == 1 and not visited[i][j]: dfs(i, j)
# 沉没孤岛(未访问的陆地变为水) for i in range(n): for j in range(m): if graph[i][j] == 1 and not visited[i][j]: graph[i][j] = 0
# 输出矩阵,注意每个元素后面有空格 for i in range(n): print(' '.join(str(cell) for cell in graph[i]) + ' ')
main()
卡码网:103. 水流问题
import sysfrom collections import dequeinput = sys.stdin.read
def main(): data = input().split() n, m = int(data[0]), int(data[1]) matrix = [] index = 2 for _ in range(n): row = list(map(int, data[index:index+m])) index += m matrix.append(row)
def bfs(starts): visited = [[False]*m for _ in range(n)] queue = deque(starts) for x, y in starts: visited[x][y] = True directions = [(1,0), (-1,0), (0,1), (0,-1)] while queue: x, y = queue.popleft() for dx, dy in directions: nx, ny = x + dx, y + dy if 0 <= nx < n and 0 <= ny < m: if not visited[nx][ny] and matrix[nx][ny] >= matrix[x][y]: visited[nx][ny] = True queue.append((nx, ny)) return visited
first_border = [(i, 0) for i in range(n)] + [(0, j) for j in range(m)] second_border = [(i, m-1) for i in range(n)] + [(n-1, j) for j in range(m)]
reachable_first = bfs(first_border) reachable_second = bfs(second_border)
result = [] for i in range(n): for j in range(m): if reachable_first[i][j] and reachable_second[i][j]: result.append((i, j))
for x, y in result: print(x, y)
main()
卡码网:104. 建造最大岛屿
import syssys.setrecursionlimit(10**7)input = sys.stdin.read
def main(): data = input().split() n, m = int(data[0]), int(data[1]) index = 2 grid = [] for _ in range(n): row = list(map(int, data[index:index+m])) index += m grid.append(row)
# 岛屿id起始为2(因为0、1已用) island_id = 2 area_map = {} # id -> 面积
def dfs(x, y, id): stack = [(x, y)] grid[x][y] = id area = 0 while stack: cx, cy = stack.pop() area += 1 for nx, ny in [(cx-1,cy),(cx+1,cy),(cx,cy-1),(cx,cy+1)]: if 0 <= nx < n and 0 <= ny < m and grid[nx][ny] == 1: grid[nx][ny] = id stack.append((nx, ny)) return area
# 标记岛屿并计算面积 for i in range(n): for j in range(m): if grid[i][j] == 1: area = dfs(i, j, island_id) area_map[island_id] = area island_id += 1
# 如果没有0,说明整张图都是陆地,直接输出面积即可 max_area = max(area_map.values()) if area_map else 0
# 遍历0,计算变成1后可能最大面积 for i in range(n): for j in range(m): if grid[i][j] == 0: neighbor_ids = set() for nx, ny in [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]: if 0 <= nx < n and 0 <= ny < m and grid[nx][ny] > 1: neighbor_ids.add(grid[nx][ny]) area_sum = 1 # 把当前0变1 for id in neighbor_ids: area_sum += area_map[id] max_area = max(max_area, area_sum)
print(max_area)
main()
代码随想录算法训练营第四十五天 | 图论 Part03
https://fuwari.vercel.app/posts/code_musings_day_forty-five/