day52 第十一章:图论part03

101. 孤岛的总面积

dfs:两种写法:一种是进来之前就判断了,判断条件在dfs的for内部;另一种是进来没有判断,那么终止条件在dfs开头。

不管哪一种写法,主函数里的判断都不能少

python 复制代码
# dfs
directions = [[0,1],[1,0],[0,-1],[-1,0]]
area = 0

def dfs(grid, x, y):
    global area
    area += 1
    grid[x][y] = 0

    # surrounding area
    for i in range(4):
        next_x = x + directions[i][0]
        next_y = y + directions[i][1]
        if next_x < 0 or next_x >=n or next_y < 0 or next_y >=m:
            continue
        if grid[next_x][next_y] == 1:
            dfs(grid, next_x, next_y)
        

if __name__ == "__main__":
    n,m = map(int, input().split())
    
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))
    # n,m = 4,5
    # grid = [[1,1,0,0,0],[1,1,0,0,0],[0,0,1,0,0],[0,0,0,1,1]]

    for j in range(m):
        if grid[0][j] == 1:
            dfs(grid, 0, j)
        if grid[-1][j] == 1:
            dfs(grid, n-1, j)
    
    for i in range(n):
        if grid[i][0] == 1:
            dfs(grid, i, 0)
        if grid[i][-1] == 1:
            dfs(grid, i, m-1)
        
    area = 0
    for i in range(1, n-1):
        for j in range(1, m-1):
            if grid[i][j] == 1:
                area += 1
                # dfs(grid, i, j)

    print(area)

bfs: 加进来的时候就变,不要等pop的时候再变。即两处append的地方,开头和for内部,都要同时加变化。

python 复制代码
# bfs
from collections import deque
directions = [[0,1],[1,0],[0,-1],[-1,0]]
area = 0

def bfs(grid, x, y):
    global area
    que = deque()
    que.append([x,y])
    # area += 1
    grid[x][y] = 0
    
    while que:
        cur_x, cur_y = que.popleft()
        for i in range(4):
            next_x = cur_x + directions[i][0]
            next_y = cur_y + directions[i][1]
            if next_x < 0 or next_x >= n or next_y < 0 or next_y >=m:
                continue
            if grid[next_x][next_y] == 1:
                que.append([next_x, next_y])
                # area += 1
                grid[next_x][next_y] = 0

        
if __name__ == "__main__":
    n,m = map(int, input().split())
    
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))
    # n,m = 4,5
    # grid = [[1,1,0,0,0],[1,1,0,0,0],[0,0,1,0,0],[0,0,0,1,1]]

    for j in range(m):
        if grid[0][j] == 1:
            bfs(grid, 0, j)
        if grid[-1][j] == 1:
            bfs(grid, n-1, j)
    
    for i in range(n):
        if grid[i][0] == 1:
            bfs(grid, i, 0)
        if grid[i][-1] == 1:
            bfs(grid, i, m-1)
        
    area = 0
    for i in range(1, n-1):
        for j in range(1, m-1):
            if grid[i][j] == 1:
                area += 1
                # dfs(grid, i, j)

    print(area)

102. 沉没孤岛

空间复杂度高了,可以不用新建一个list,而是把陆地改成2,以示区分,然后遍历,再把孤岛改成0,陆地改成1

dfs: 进入条件即退出条件,二者选一即可

python 复制代码
# DFS
dire = [[0,1],[1,0],[0,-1],[-1,0]]
def dfs(grid, x, y):
    grid[x][y] = 0
    
    for i in range(4):
        next_x = x + dire[i][0]
        next_y = y + dire[i][1]
        if next_x < 0 or next_x >= n or next_y < 0 or next_y >= m:
            continue
        if grid[next_x][next_y] == 1:
            dfs(grid, next_x, next_y)
    

if __name__ == "__main__":
    n,m = map(int, input().split())
    
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))
        
    # deepcopy instead of shallow copy
    grid_2 = [nested[:] for nested in grid]
    
    # erase mainland
    for i in range(n):
        if grid[i][0] == 1:
            dfs(grid, i, 0)
        if grid[i][-1] == 1:
            dfs(grid, i, m-1)
            
    for j in range(m):
        if grid[0][j] == 1:
            dfs(grid, 0, j)
        if grid[-1][j] == 1:
            dfs(grid, n-1, j)

    # mainland = all - isolated islands
    for i in range(n):
        for j in range(m):
            grid[i][j] = grid_2[i][j] - grid[i][j]

    # output
    for i in range(n):
        print(" ".join(map(str, grid[i])))
  
        
    
    

bfs

python 复制代码
# DFS
from collections import deque
dire = [[0,1],[1,0],[0,-1],[-1,0]]

def bfs(grid, x, y):
    que = deque()
    que.append([x,y])
    grid[x][y] = 0
    while que:
        cur_x, cur_y = que.popleft()
        for i in range(4):
            next_x = cur_x + dire[i][0]
            next_y = cur_y + dire[i][1]
            if next_x < 0 or next_x >= n or next_y < 0 or next_y >= m:
                continue
            if grid[next_x][next_y] == 1:
                que.append([next_x, next_y])
                grid[next_x][next_y] = 0
            

if __name__ == "__main__":
    n,m = map(int, input().split())
    
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))
        
    # deepcopy instead of shallow copy
    grid_2 = [nested[:] for nested in grid]
        
    for i in range(n):
        if grid[i][0] == 1:
            bfs(grid, i, 0)
        if grid[i][-1] == 1:
            bfs(grid, i, m-1)
            
    for j in range(m):
        if grid[0][j] == 1:
            bfs(grid, 0, j)
        if grid[-1][j] == 1:
            bfs(grid, n-1, j)
    
    for i in range(n):
        for j in range(m):
            grid[i][j] = grid_2[i][j] - grid[i][j]

    for i in range(n):
        print(" ".join(map(str, grid[i])))

103.水流问题

dfs, bfs流程都差不多,主要看在图的处理上,怎么需要dfs,bfs

dfs:

python 复制代码
# DFS
# from collections import deque
dire = [[0,1],[-1,0],[1,0],[0,-1]] #上,左,右,下
# first = False
# second = False

def dfs(grid, visited, x, y):
    # 从(x,y)出发,看水流能逆流到哪里去
    # 即顺流的逆运算
    # 因为顺流的起始点太多,是整个矩阵,
    # 但逆流只有边界,所以从边界出发,进行逆运算,判断哪里能逆流上去,复杂度比较简单
    visited[x][y] = True
    
    for i in range(4):
        next_x = x + dire[i][0]
        next_y = y + dire[i][1]
        if next_x < 0 or next_x >= n or next_y < 0 or next_y >= m:
            continue
        if grid[next_x][next_y] >= grid[x][y] and not visited[next_x][next_y]:
            # not visited 条件不可少,这里用flowable更准确
            # 看边界能否逆流到这里, (next_x. next_y)
            # and 前后顺序可以颠倒,因为我只看这个格子能不能从边界逆流而上,
            # 不看从哪里逆流而上
            # 在第一/第二边界分开时,不用管从哪里流过来
            dfs(grid, visited, next_x, next_y)

       
if __name__ == "__main__":
    n,m = map(int, input().split())
    
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))
    
    first = [[False]*m for _ in range(n)]
    second = [[False]*m for _ in range(n)]
    # visited = [[False]*m for _ in range(n)]


    for i in range(n):
        dfs(grid, first, i, 0)
        dfs(grid, second, i, m-1)
    
    for j in range(m):
        dfs(grid, first, 0, j)
        dfs(grid, second, n-1, j)
        
    for i in range(n):
        for j in range(m):
            if first[i][j] and second[i][j]:
                print(f"{i} {j}")
                

bfs:

python 复制代码
# BFS
from collections import deque
dire = [[0,1],[-1,0],[1,0],[0,-1]] #上,左,右,下
# first = False
# second = False

def bfs(grid, visited, x, y):
    que = deque()
    que.append([x,y])
    visited[x][y] = True
    # print(f"({x}{y})")
    while que:
        cur_x, cur_y = que.popleft()
        for i in range(4):
            next_x = cur_x + dire[i][0]
            next_y = cur_y + dire[i][1]
            if next_x < 0 or next_x >= n or next_y < 0 or next_y >= m:
                continue
            if grid[next_x][next_y] >= grid[cur_x][cur_y] and not visited[next_x][next_y]:
                que.append([next_x, next_y])
                visited[next_x][next_y] = True

        
       
if __name__ == "__main__":
    n,m = map(int, input().split())
    
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))

    # n, m = 5,5
    # grid = [[1,3,1,2,4],
    # [1,2,1,3,2],
    # [2,4,7,2,1],
    # [4,5,6,1,1],
    # [1,4,1,2,1]]

    first = [[False]*m for _ in range(n)]
    second = [[False]*m for _ in range(n)]


    for i in range(n):
        bfs(grid, first, i, 0)
        bfs(grid, second, i, m-1)
    
    for j in range(m):
        bfs(grid, first, 0, j)
        bfs(grid, second, n-1, j)
        
    for i in range(n):
        for j in range(m):
            if first[i][j] and second[i][j]:
                print(f"{i} {j}")
                

104.建造最大岛屿

dfs

python 复制代码
# DFS
# from collections import deque
from collections import defaultdict
dire = [[0,1],[-1,0],[1,0],[0,-1]] #上,左,右,下
count = 0

def dfs(grid, x, y, mark):
    if grid[x][y] != 1:
        return
    
    global count
    grid[x][y] = mark
    count += 1
    
    for i in range(4):
        next_x = x + dire[i][0]
        next_y = y + dire[i][1]
        if next_x < 0 or next_x >= n or next_y < 0 or next_y >= m:
            continue
        dfs(grid, next_x, next_y, mark)


if __name__ == "__main__":
    n,m = map(int, input().split())
    
    grid = []
    for _ in range(n):
        grid.append(list(map(int, input().split())))

#     n,m = 4,5
#     grid = [[1,1,0,0,0],
# [1,1,0,0,0],
# [0,0,1,0,0],
# [0,0,0,1,1]]

    grid_num = defaultdict(int)
    
    mark = 2
    ocean_flag = False
    
    for i in range(n):
        for j in range(m):
            if grid[i][j] == 1:
                count = 0
                dfs(grid, i, j, mark)
                grid_num[mark] = count
                mark += 1
                continue
            if grid[i][j] == 0:
                ocean_flag = True
    
    result = 0
    area = 0
    if ocean_flag == False:
        for key in grid_num.keys():
            result += grid_num[key]
    else:
        for i in range(n):
            for j in range(m):
                if grid[i][j] == 0:
                    area = 1
                    added_grid = set()
                    for k in range(4):
                        new_x = i + dire[k][0]
                        new_y = j + dire[k][1]
                        if new_x < 0 or new_x >= n or new_y < 0 or new_y >= m:
                            continue
                        if grid[new_x][new_y] != 0 and grid[new_x][new_y] not in added_grid:
                            added_grid.add(grid[new_x][new_y])
                            area += grid_num[grid[new_x][new_y]]
                            # print(f"({new_x},{new_y}) {area}")
                            # print(f"{area}")
                    result = max(result, area)
                
    print(result)

bfs

python 复制代码
from collections import deque
from collections import defaultdict
dire = [[0,1],[-1,0],[1,0],[0,-1]] #上,左,右,下
count = 0

def bfs(grid, x, y, mark):
    global count
    que = deque()
    que.append([x,y])
    grid[x][y] = mark
    count += 1
    while que:
        cur_x, cur_y = que.popleft()
        for i in range(4):
            next_x = cur_x + dire[i][0]
            next_y = cur_y + dire[i][1]
            if next_x < 0 or next_x >= n or next_y < 0 or next_y >= m:
                continue
            if grid[next_x][next_y] == 1:
                que.append([next_x,next_y])
                grid[next_x][next_y] = mark
                count += 1
相关推荐
尼尔森系3 小时前
排序与算法:希尔排序
c语言·算法·排序算法
AC使者4 小时前
A. C05.L08.贪心算法入门
算法·贪心算法
冠位观测者4 小时前
【Leetcode 每日一题】624. 数组列表中的最大距离
数据结构·算法·leetcode
yadanuof4 小时前
leetcode hot100 滑动窗口&子串
算法·leetcode
可爱de艺艺4 小时前
Go入门之函数
算法
武乐乐~4 小时前
欢乐力扣:旋转图像
算法·leetcode·职场和发展
a_j585 小时前
算法与数据结构(子集)
数据结构·算法·leetcode
清水加冰5 小时前
【算法精练】背包问题(01背包问题)
c++·算法
慢一点会很快7 小时前
FRRouting配置与OSPF介绍,配置,命令,bfd算法:
算法·智能路由器·php·ospf
88号技师8 小时前
2024年中科院一区SCI-雪雁优化算法Snow Geese Algorithm-附Matlab免费代码
开发语言·人工智能·算法·matlab·优化算法