851 字
4 分钟
代码随想录算法训练营第四十五天 | 图论 Part03

卡码网:101. 孤岛的总面积#

题目链接

import sys
sys.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 sys
input = sys.stdin.read
sys.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 sys
from collections import deque
input = 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 sys
sys.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/
作者
Jarrett
发布于
2025-08-01
许可协议
CC BY-NC-SA 4.0