20240821 代码随想录 | 图论

103. 水流问题

dfs深度优先搜素

directions = [[0,1], [0,-1], [1,0], [-1,0]]
set_1 = set()
set_2 = set()
n, m = map(int, input().split())
g = []
for _ in range(n):
    g.append(list(map(int, input().split())))

def dfs(g, x, y, visited, s):
    visited[x][y] = True
    # 注意这里因为s是集合
    # 在Python中,集合(set)可以包含任何不可变类型(如整数、浮点数、字符串、元组等)作为元素。然而,由于列表(list)是可变类型,它不能作为集合的元素。
    s.add((x,y))
    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 not visited[next_x][next_y] and g[next_x][next_y]>=g[x][y]:
            dfs(g, next_x, next_y, visited, s)
    
visited = [[False]*m for _ in range(n)]
for i in range(n):
    if not visited[i][0]:
        dfs(g, i, 0, visited, set_1)
for j in range(m):
    if not visited[0][j]:
        dfs(g, 0, j, visited, set_1)

# 注意:这里考虑第二组边界的时候visited需要重置,否则一些能到达的点无法标记到set_2
visited = [[False]*m for _ in range(n)]
for i in range(n):
    if not visited[i][m-1]:
        dfs(g, i, m-1, visited, set_2)
for j in range(m):
    if not visited[n-1][j]:
        dfs(g, n-1, j, visited, set_2)

result = set_1 & set_2

for i in result:
    print(" ".join(map(str, i)))

bfs广度优先搜索

from collections import deque
directions = [[0,1], [0,-1], [1,0], [-1,0]]
set_1 = set()
set_2 = set()
n, m = map(int, input().split())
g = []
for _ in range(n):
    g.append(list(map(int, input().split())))

def bfs(g, x, y, visited, s):
    que = deque()
    visited[x][y] = True
    # 注意这里因为s是集合
    # 在Python中,集合(set)可以包含任何不可变类型(如整数、浮点数、字符串、元组等)作为元素。然而,由于列表(list)是可变类型,它不能作为集合的元素。
    s.add((x,y))
    que.append([x,y])
    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 not visited[next_x][next_y] and g[next_x][next_y]>=g[x][y]:
                visited[next_x][next_y] = True
                s.add((next_x, next_y))
                que.append([next_x, next_y])
    
visited = [[False]*m for _ in range(n)]
for i in range(n):
    if not visited[i][0]:
        bfs(g, i, 0, visited, set_1)
for j in range(m):
    if not visited[0][j]:
        bfs(g, 0, j, visited, set_1)

# 注意:这里考虑第二组边界的时候visited需要重置,否则一些能到达的点无法标记到set_2
visited = [[False]*m for _ in range(n)]
for i in range(n):
    if not visited[i][m-1]:
        bfs(g, i, m-1, visited, set_2)
for j in range(m):
    if not visited[n-1][j]:
        bfs(g, n-1, j, visited, set_2)

result = set_1 & set_2

for i in result:
    print(" ".join(map(str, i)))

104.建造最大岛屿

dfs深度优先搜索:

directions = [[0,1], [0,-1], [1,0], [-1,0]]
n, m = map(int, input().split())
g = []
map_dict = {}
num = 1
for _ in range(n):
    g.append(list(map(int, input().split())))

def dfs(g, x, y, num):
    g[x][y] = num
    map_dict[num] += 1
    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, num)

isallgrand = True
for i in range(n):
    for j in range(m):
        if g[i][j] == 1:
            num += 1
            map_dict[num] = 0
            dfs(g, i, j, num)
        if g[i][j] == 0:
            isallgrand = False
# 注意全是陆地的情况
if isallgrand:
    print(n*m)
else:   
    result = 0
    for i in range(n):
        for j in range(m):
            if g[i][j] == 0:
                cur = 1
                visited = []
                for d in directions:
                    next_x = i + d[0]
                    next_y = j + 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] not in visited and g[next_x][next_y] > 0:
                        cur += map_dict[g[next_x][next_y]]
                        # 注意一个海水被同一片陆地在不同方向包围的情况
                        visited.append(g[next_x][next_y])
                result = max(result, cur)
    
    print(result)              

bfs广度优先搜索:

from collections import deque
directions = [[0,1], [0,-1], [1,0], [-1,0]]
n, m = map(int, input().split())
g = []
map_dict = {}
num = 1
for _ in range(n):
    g.append(list(map(int, input().split())))

def bfs(g, x, y, num):
    que = deque()
    g[x][y] = num
    map_dict[num] += 1
    que.append([x,y])
    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] = num
                map_dict[num] += 1
                que.append([next_x, next_y])

isallgrand = True
for i in range(n):
    for j in range(m):
        if g[i][j] == 1:
            num += 1
            map_dict[num] = 0
            bfs(g, i, j, num)
        if g[i][j] == 0:
            isallgrand = False
# 注意全是陆地的情况
if isallgrand:
    print(n*m)
else:   
    result = 0
    for i in range(n):
        for j in range(m):
            if g[i][j] == 0:
                cur = 1
                visited = []
                for d in directions:
                    next_x = i + d[0]
                    next_y = j + 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] not in visited and g[next_x][next_y] > 0:
                        cur += map_dict[g[next_x][next_y]]
                        # 注意一个海水被同一片陆地在不同方向包围的情况
                        visited.append(g[next_x][next_y])
                result = max(result, cur)
    
    print(result)              

 110. 字符串接龙

 

from collections import deque
n = int(input())
beginStr, endStr = map(str, input().split())
strList = set()
for _ in range(n):
    strList.add(input())

def find():
    q = deque()
    q.append(beginStr)
    visited = {beginStr: 1}
    
    while q:
        cur_s = q.popleft()
        cur_step = visited[cur_s]
        for i in range(len(cur_s)):
            for j in range(26):
                new_s = cur_s[:i] + chr(ord('a') + j) + cur_s[i+1:]
                if new_s == endStr:
                    return cur_step+1
                if new_s in strList and new_s not in visited:
                    visited[new_s] = cur_step + 1
                    q.append(new_s)

    return 0
    
print(find())

105.有向图的完全可达性

n,k = map(int, input().split())
table = [[] for _ in range(n+1)]
for _ in range(k):
    i,j = map(int, input().split())
    table[i].append(j)
    
accessible = []

def dfs(table, key, accessible):
    accessible.append(key)
    if not table[key]:
        return
    keys = table[key]
    for key in keys:
        if key not in accessible:
            dfs(table, key, accessible)

dfs(table, 1, accessible)
result = 1   
for i in range(1, n+1):
    if i not in accessible:
        result = -1
        break
    
print(result)

 106. 岛屿的周长

n,m = map(int, input().split())
g = []
for _ in range(n):
    g.append(list(map(int, input().split())))

directions = [[0,1], [0,-1], [1,0], [-1,0]]  
result = 0
for i in range(n):
    for j in range(m):
        if g[i][j] == 1:
            for d in directions:
                x = i + d[0]
                y = j + d[1]
                if x < 0  or x >= n or y < 0 or y >= m or g[x][y] == 0:
                    result += 1
print(result)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值