Day51-图论

101. 孤岛总面积

101. 孤岛的总面积

深搜
python 复制代码
DIR = [[0,1],[1,0],[0,-1],[-1,0]]

def dfs(graph,x,y):
    if not graph[x][y]:
        return
    graph[x][y] = 0
    for i in range(4):
        nextx = x + DIR[i][0]
        nexty = y + DIR[i][1]
        if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
            continue
        dfs(graph,nextx,nexty)


def main():
    n,m = map(int,input().split())
    graph = []
    for _ in range(n):
        graph.append(list(map(int,input().split())))
    # visited = [[0]*m for _ in range(n)]
    # 孤岛的定义:周围不接触边缘的岛屿
    # 一个思路是,将周围接触边缘的岛屿全部置为0,最终统计graph中1的个数
    # 遍历4条边,将其中相邻的陆地岛屿全部置为0
    # 这里不需要visited,因为我们直接修改了graph,相当于同步完成了visited工作
    for i in range(n):
        if graph[i][0]:
            dfs(graph,i,0)
        if graph[i][m-1]:
            dfs(graph,i,m-1)
    for j in range(m):
        if graph[0][j]:
            dfs(graph,0,j)
        if graph[n-1][j]:
            dfs(graph,n-1,j)
    res = sum([sum(graph[i]) for i in range(n)])
    print(res)


if __name__ == '__main__':
    main()
广搜
python 复制代码
DIR = [[0,1],[1,0],[0,-1],[-1,0]]


def bfs(graph,x,y):
    queue = []
    queue.append([x,y])
    while queue:
        x,y = queue.pop()
        graph[x][y] = 0
        for i in range(4):
            nextx = x + DIR[i][0]
            nexty = y + DIR[i][1]
            if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
                continue 
            if graph[nextx][nexty]:
                queue.append([nextx,nexty])

def main():
    n,m = map(int,input().split())
    graph = []
    for _ in range(n):
        graph.append(list(map(int,input().split())))
    # visited = [[0]*m for _ in range(n)]
    # 孤岛的定义:周围不接触边缘的岛屿
    # 一个思路是,将周围接触边缘的岛屿全部置为0,最终统计graph中1的个数
    # 遍历4条边,将其中相邻的陆地岛屿全部置为0
    # 这里不需要visited,因为我们直接修改了graph,相当于同步完成了visited工作
    for i in range(n):
        if graph[i][0]:
            bfs(graph,i,0)
        if graph[i][m-1]:
            bfs(graph,i,m-1)
    for j in range(m):
        if graph[0][j]:
            bfs(graph,0,j)
        if graph[n-1][j]:
            bfs(graph,n-1,j)
    res = sum([sum(graph[i]) for i in range(n)])
    print(res)


if __name__ == '__main__':
    main()

102. 沉没孤岛

102. 沉没孤岛

可以构造一个visited,将周边全部记录为1,中间的孤岛的visited不查看,最后全部置为0

但是也可以直接使用graph,将非孤岛置为2,最后还原!

深搜
python 复制代码
DIR = [[0,1],[1,0],[0,-1],[-1,0]]

def dfs(graph,x,y):
    if graph[x][y] != 1:
        return
    graph[x][y] = 2
    for i in range(4):
        nextx = x + DIR[i][0]
        nexty = y + DIR[i][1]
        if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
            continue
        dfs(graph,nextx,nexty)

def main():
    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]:
            dfs(graph,i,0)
        if graph[i][m-1]:
            dfs(graph,i,m-1)
    for j in range(m):
        if graph[0][j]:
            dfs(graph,0,j)
        if graph[n-1][j]:
            dfs(graph,n-1,j)
    for i in range(n):
        for j in range(m):
            if graph[i][j] == 1:
                graph[i][j] = 0
            elif graph[i][j] == 2:
                graph[i][j] = 1
    for r in graph:
        print(' '.join(map(str,r)))


if __name__ == '__main__':
    main()
广搜
python 复制代码
DIR = [[0,1],[1,0],[0,-1],[-1,0]]

def bfs(graph,x,y):
    queue = []
    queue.append([x,y])
    while queue:
        x,y = queue.pop()
        graph[x][y] = 2
        for i in range(4):
            nextx = x + DIR[i][0]
            nexty = y + DIR[i][1]
            if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
                continue 
            if graph[nextx][nexty]==1:
                queue.append([nextx,nexty])

def main():
    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]:
            bfs(graph,i,0)
        if graph[i][m-1]:
            bfs(graph,i,m-1)
    for j in range(m):
        if graph[0][j]:
            bfs(graph,0,j)
        if graph[n-1][j]:
            bfs(graph,n-1,j)
    for i in range(n):
        for j in range(m):
            if graph[i][j] == 1:
                graph[i][j] = 0
            elif graph[i][j] == 2:
                graph[i][j] = 1
    for r in graph:
        print(' '.join(map(str,r)))


if __name__ == '__main__':
    main()

103. 高山流水

103. 高山流水

暴力思路:遍历每一个节点,对于每个节点使用深搜或者广搜,看看是否会达到边界(时间复杂度

逆向思考:我们找到第一边界和第二边界从低往高走的所有点,两个的交集就是我们要找的"高山"。(时间复杂度()由于不会重复访问同一个节点,所以实际复杂度更低

python 复制代码
DIR = [[0,1],[1,0],[0,-1],[-1,0]]

def dfs(graph,visited,x,y):
    if visited[x][y]:
        return
    visited[x][y] = 1
    for i in range(4):
        nextx = x + DIR[i][0]
        nexty = y + DIR[i][1]
        if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
            continue
        if graph[x][y] <= graph[nextx][nexty]:
            dfs(graph,visited,nextx,nexty)

def main():
    n,m = map(int,input().split())
    graph = []
    for _ in range(n):
        graph.append(list(map(int,input().split())))
    isfirst = [[0]*m for _ in range(n)]
    issecond = [[0]*m for _ in range(n)]
    for i in range(n):
        dfs(graph,isfirst,i,0)
        dfs(graph,issecond,i,m-1)
    for j in range(m):
        dfs(graph,isfirst,0,j)
        dfs(graph,issecond,n-1,j)
    for i in range(n):
        for j in range(m):
            if isfirst[i][j] and issecond[i][j]:
                print(f"{i} {j}") 

if __name__ == '__main__':
    main()

104. 建造最大岛屿

104. 建造最大岛屿

python 复制代码
DIR = [[0,1],[1,0],[0,-1],[-1,0]]
count = 0

def dfs(graph,visited,x,y,mask):
    global count
    if visited[x][y] or graph[x][y] != 1:
        return
    visited[x][y] = 1
    graph[x][y] = mask
    count +=1
    for i in range(4):
        nextx = x + DIR[i][0]
        nexty = y + DIR[i][1]
        if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
            continue
        dfs(graph,visited,nextx,nexty,mask) 

def main():
    global count
    n,m = map(int,input().split())
    graph = []
    for _ in range(n):
        graph.append(list(map(int,input().split())))
    visited = [[0]*m for _ in range(n)]
    d = {0:0}
    mask = 2
    res = 0
    for i in range(n):
        for j in range(m):
            if graph[i][j] and not visited[i][j]:
                # 统计岛屿面积
                count = 0
                dfs(graph,visited,i,j,mask)
                d[mask] = count
                mask +=1 
    for i in range(n):
        for j in range(m):
            if not graph[i][j]:
                tmp = set()
                for c in range(4):
                    nextx = i + DIR[c][0]
                    nexty = j + DIR[c][1]
                    if nextx<0 or nexty<0 or nextx>=len(graph) or nexty>=len(graph[0]):
                        continue
                    if graph[nextx][nexty]>1:
                        tmp.add(graph[nextx][nexty])
                res = max(res,1+sum([d[x] for x in tmp]))
    if res == 0:
        # 注意:d中包含{0:0},所以需要排除0
        res = max(d.values())
    print(res)

if __name__ == '__main__':
    main()
相关推荐
卷无止境6 小时前
Python的方法解析顺序:一场关于继承顺序的精妙设计
后端·python
小龙报6 小时前
【优选算法】1. 水果成蓝 2.找到字符串中所有字母的异位词
java·c语言·数据结构·数据库·c++·redis·算法
wWYy.7 小时前
数据结构:跳表
数据结构
小柯南敲键盘7 小时前
跨马翻译:批量图片与视频字幕翻译,支持智能抠图
大数据·人工智能·python·音视频
txzrxz7 小时前
数论:排列数、组合数、费马小定理、逆元、同余定理
c++·算法·数论·组合数·费马小定理·逆元·排列数
再渊7 小时前
基因归因到底怎么计算的?
python·深度学习·机器学习
xqqxqxxq7 小时前
LeetCode Hot100 双指针专项题解笔记
笔记·算法·leetcode
E_ICEBLUE7 小时前
Python 拆分 Excel 文件:使用 Spire.XLS 实现按工作表、行、列和条件拆分
python·excel
aiqianji8 小时前
有哪些稳定的AI短篇小说写作软件可以推荐?
人工智能·python
闪电悠米8 小时前
力扣hot100-54.螺旋矩阵-模拟边界控制详解
算法·leetcode·矩阵