20240820 代码随想录 | 图论 岛屿

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])))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值