BFS广度优先搜索-Python

洪水覆盖算法(Flood Fill)

AcWing 1097. 池塘计数

https://www.acwing.com/problem/content/1099/
请添加图片描述

from collections import deque

xdis = [-1,1,0,0,-1,1,-1,1]
ydis = [0,0,-1,1,-1,-1,1,1]

def bfs(x,y):
    dq = deque([[x,y]])
    maze[x][y] = '.'
    while dq:
        x,y = dq.popleft()
        for i in range(8):
            x1 = x+xdis[i]
            y1 = y+ydis[i]
            if x1<1 or x1>n or y1<1 or y1>m:
                continue
            if maze[x1][y1] =='.':
                continue
            dq.append([x1,y1])
            maze[x1][y1] = '.'

n,m = map(int,input().split())
maze = [['.'] for i in range(n+1)]
for i in range(n):
    maze[i+1].extend(list(input()))

res = 0
for i in range(1,n+1):
    for j in range(1,m+1):
        if maze[i][j]=='W':
            # print(i,j)
            res += 1
            bfs(i,j)
# print(maze)
print(res)


AcWing 1098. 城堡问题

https://www.acwing.com/problem/content/1100/

请添加图片描述

from collections import deque

xdirs = [0,-1,0,1]
ydirs = [-1,0,1,0]


def bfs(x,y):
    dq = deque([[x,y]])
    visited[x][y] = 1
    ans = 1
    while dq:
        x,y = dq.popleft()
        for i in range(4):
            if not maze[x][y]>>i & 1:
                x1,y1 = x+xdirs[i],y+ydirs[i]
                if visited[x1][y1]:
                    continue
                ans += 1
                dq.append((x1,y1))
                visited[x1][y1] = 1
    return ans
    

n,m = map(int,input().split())
visited = [[0]*(m+1) for i in range(n+1)]
maze = [[0] for i in range(n+1)]
for i in range(n):
    maze[i+1].extend(list(map(int,input().split())))

res = 0
ans = 0
for i in range(1,n+1):
    for j in range(1,m+1):
        if not visited[i][j]:
            ans = max(ans,bfs(i,j))
            res += 1
# bfs(1,1)
print(res)
print(ans)
AcWing 1106. 山峰和山谷

https://www.acwing.com/problem/content/1108/

请添加图片描述

from collections import deque

xdirs = [0, 0, 1, -1, 1, -1, 1, -1]
ydirs = [1, -1, 0, 0, 1, -1, -1, 1]


def bfs(x, y):
    global max_res, min_res
    num = maze[x][y]
    dq = deque([[x, y]])
    visited[x][y] = 1
    is_min = True
    is_max = True
    while dq:
        x, y = dq.popleft()
        for i in range(8):
            x1, y1 = x + xdirs[i], y + ydirs[i]
            if x1 < 1 or x1 > n or y1 < 1 or y1 > n:
                continue
            if is_max and maze[x1][y1] > num:
                is_max = False
            if is_min and maze[x1][y1] < num:
                is_min = False
            if maze[x1][y1] == num and not visited[x1][y1]:
                visited[x1][y1] = True
                dq.append((x1, y1))
    if is_min:
        min_res += 1
    if is_max:
        max_res += 1


n = int(input())
maze = [[0] for i in range(n + 1)]
visited = [[0] * (n + 1) for i in range(n + 1)]
max_res = 0
min_res = 0
for i in range(n):
    maze[i + 1].extend(list(map(int, input().split())))

for i in range(1, n + 1):
    for j in range(1, n + 1):
        if not visited[i][j]:
            bfs(i, j)

print(max_res, min_res)

最短路模型

AcWing 1076. 迷宫问题

https://www.acwing.com/problem/content/1078/

请添加图片描述

from collections import deque

xdirs = [0,0,-1,1]
ydirs = [1,-1,0,0]


def bfs(x,y):
    dq = deque([[x,y]])
    maze[x][y] = 1
    while dq:
        x,y = dq.popleft()
        for i in range(4):
            x1,y1 = x+xdirs[i],y+ydirs[i]
            if x1<0 or x1>=n or y1<0 or y1>=n or maze[x1][y1]==1:
                continue
            maze[x1][y1] = 1
            dq.append((x1,y1))
            path[x1][y1] = (x,y)

n = int(input())
maze = []
path = [[None]*n for i in range(n)]
for i in range(n):
    maze.append(list(map(int,input().split())))
bfs(n-1,n-1)

i,j = 0,0
while True:
    if i==n-1 and j==n-1:
        break
    print(i,j)
    i,j = path[i][j]
print(n-1,n-1)
# print(path)

AcWing 188. 武士风度的牛

https://www.acwing.com/problem/content/190/

请添加图片描述

from collections import deque

xdirs = [-1,-1,1,1,-2,-2,2,2]
ydirs = [2,-2,2,-2,1,-1,1,-1]

def bfs(x,y):
    dq = deque([[x,y]])
    maze[x][y] = '*'
    while dq:
        x,y = dq.popleft()
        for i in range(8):
            x1,y1 = x+xdirs[i],y+ydirs[i]
            if x1<0 or x1>=n or y1<0 or y1>=m or maze[x1][y1]=='*':
                continue
            maze[x1][y1] = '*'
            cnt[x1][y1] = cnt[x][y]+1
            dq.append((x1,y1))

m,n = map(int,input().split())
maze = []
cnt = [[0]*m for i in range(n)]
for i in range(n):
    maze.append(list(input()))
# print(maze)
for i in range(n):
    for j in range(m):
        if maze[i][j]=='H':
            res = (i,j)


for i in range(n):
    for j in range(m):
        if maze[i][j]=='K':
            bfs(i,j)
print(cnt[res[0]][res[1]])

AcWing 1100. 抓住那头牛

https://www.acwing.com/problem/content/1102/

请添加图片描述

from collections import deque

xdirs = {
    lambda x:x-1,
    lambda x:x+1,
    lambda x:x*2
}

N,K = map(int,input().split())
maze = [0 for i in range(100050)]
dq = deque()
dq.append(N)
maze[N] = 1
while dq:
    x = dq.popleft()
    if x == K:
        break
    for xdi in xdirs:
        x1 = xdi(x)
        if x1<0 or x1>=100050 or maze[x1]:
            continue
        maze[x1] = maze[x]+1
        dq.append(x1)
# print(maze)
print(maze[K]-1)

多源BFS

AcWing 173. 矩阵距离

https://www.acwing.com/problem/content/175/

请添加图片描述

from collections import deque

xdirs = [0,0,1,-1]
ydirs = [1,-1,0,0]

def bfs():
    is_visited = [[0]*m for i in range(n)]
    dq = deque()
    for i in range(n):
        for j in range(m):
            if maze[i][j]=='1':
                dq.append((i,j))
                is_visited[i][j] = 1
    while dq:
        x,y = dq.popleft()
        for i in range(4):
            x1,y1 = x+xdirs[i],y+ydirs[i]
            if x1<0 or x1>=n or y1<0 or y1>=m or is_visited[x1][y1] or maze[x1][y1]=='1':
                continue
            cnt[x1][y1] = cnt[x][y]+1
            dq.append((x1,y1))
            is_visited[x1][y1] = 1

n,m = map(int,input().split())
maze = [list(input()) for i in range(n)]
cnt = [[0]*m for i in range(n)]
bfs()
for i in range(n):
    print(*cnt[i])

最小步数模型

AcWing 1107. 魔板

https://www.acwing.com/problem/content/1109/

请添加图片描述

from collections import deque

def A(li):
    lis = li[::-1]
    return lis
    
def B(li):
    lis = (li[3],)+li[:3]+li[5:8]+(li[4],)
    return lis

def C(li):
    lis = []
    lis.append(li[0])
    lis.append(li[6])
    lis.append(li[1])
    lis.append(li[3])
    lis.append(li[4])
    lis.append(li[2])
    lis.append(li[5])
    lis.append(li[7])
    return tuple(lis)
    
start = tuple(map(int,input().split()))
d = {}

dq = deque()
dq.append((1,2,3,4,5,6,7,8))
d[(1,2,3,4,5,6,7,8)] = ('',None)

while dq:
    s = dq.popleft()
    if s==start:
        break
    s1 = A(s)
    if s1 not in d:
        dq.append(s1)
        d[s1] = ('A',s)
    s2 = B(s)
    if s2 not in d:
        dq.append(s2)
        d[s2] = ('B',s)
    s3 = C(s)
    if s3 not in d:
        dq.append(s3)
        d[s3] = ('C',s)
cnt = 0
res = ''
# print(d)
s = (1,2,3,4,5,6,7,8)
while s != start:
    cnt += 1
    res += d[start][0]
    start = d[start][1]
print(cnt)
if cnt:
    print(res[::-1])

双端队列广搜

AcWing 175. 电路维修

https://www.acwing.com/problem/content/177/

请添加图片描述

from collections import deque

xdirs = [1,1,-1,-1]
ydirs = [1,-1,1,-1]
xi = [0,0,-1,-1]
yi = [0,-1,0,-1]
ma = ['\\','/','/','\\']


def bfs():
    x,y = 0,0
    dq = deque()
    dq.append((x,y))
    while dq:
        x,y = dq.popleft()
        if x==n and y==m:
            return dist[x][y]
        if visited[x][y]:
            continue
        visited[x][y] = True
        for i in range(4):
            x1,y1 = x+xdirs[i],y+ydirs[i]
            if x1<0 or x1>n or y1<0 or y1>m:
                continue
            x2,y2 = x+xi[i],y+yi[i]
            w = maze[x2][y2] != ma[i]
            if dist[x1][y1]>dist[x][y]+w:
                dist[x1][y1] = dist[x][y]+w
                if not w:
                    dq.appendleft((x1,y1))
                else:
                    dq.append((x1,y1))
        
    

T = int(input())
for _ in range(T):
    maze = []
    n,m = map(int,input().split())
    for i in range(n):
        maze.append(list(input()))
    visited = [[False]*(m+1) for i in range(n+1)]
    dist = [[float('inf')]*(m+1) for i in range(n+1)]
    dist[0][0] = 0
    if (m+n)%2:
        print('NO SOLUTION')
    else:
        res = bfs()
        print(res)
    

双向广搜

AcWing 190. 字串变换

https://www.acwing.com/problem/content/192/
请添加图片描述

import sys
from collections import deque


def check(dq, da, db, a, b):
    # 每次只搜一层
    # for i in range(len(dq)):
    d = da[dq[0]]
    while dq and da[dq[0]] == d:
        s = dq.popleft()
        for di in zip(a, b):
            idx = -1
            while idx < len(s):
                idx = s.find(di[0], idx + 1)
                if idx == -1:
                    break
                new_s = s[:idx] + s[idx:].replace(di[0], di[1], 1)
                if new_s in db:
                    return da[s] + 1 + db[new_s]
                if new_s not in da:
                    # print(new_s)
                    da[new_s] = da[s] + 1
                    dq.append(new_s)
    return 11


def bfs():
    if start == end:
        return 0
    start_dq = deque()
    end_dq = deque()
    sdic = {}
    edic = {}
    sdic[start] = 0
    edic[end] = 0
    start_dq.append(start)
    end_dq.append(end)
    step = 0
    while start_dq and end_dq:
        if len(start_dq) < len(end_dq):
            t = check(start_dq, sdic, edic, a, b)
        else:
            t = check(end_dq, edic, sdic, b, a)
        if t <= 10:
            return t
        step += 1
        if step == 10:
            return -1
    return -1


start, end = input().split()
a = []
b = []
for line in sys.stdin:
    u, v = line.split()
    a.append(u)
    b.append(v)
res = bfs()
if res != -1:
    print(res)
else:
    print('NO ANSWER!')

A*算法

AcWing 178. 第K短路

https://www.acwing.com/problem/content/180/

请添加图片描述

import heapq


def djs(u):
    dist[u] = 0
    hp = []
    heapq.heappush(hp,(0,u))
    visited = [False for i in range(N+1)]
    while hp:
        u = heapq.heappop(hp)[1]
        if visited[u]:
            continue
        visited[u] = True
        for v,w in D[u]:
            if dist[u]+w<dist[v]:
                dist[v] = dist[u]+w
                heapq.heappush(hp,(dist[v],v))
    

def Astar(S):
    hp = []
    heapq.heappush(hp,(dist[S],(0,S)))
    while hp:
        dis,u = heapq.heappop(hp)[1]
        cnt[u]+=1
        if cnt[T]==K:
            return dis
        for v,w in G[u]:
            if cnt[v]<K:
                heapq.heappush(hp,(dis+w+dist[v],(dis+w,v)))
    return -1
    
    

N,M = map(int,input().split())
G = [[] for i in range(N+1)]
D = [[] for i in range(N+1)]
for i in range(M):
    u,v,w = map(int,input().split())
    G[u].append((v,w))
    # 反向迪杰斯特拉邻接表
    D[v].append((u,w))
S,T,K = map(int,input().split())

dist = [float('inf') for i in range(N+1)]
djs(T)

cnt = [0 for i in range(N+1)]
# print(dist)
# 去除等于0直接输出的这个方案
if S==T:
    K+=1
print(Astar(S))
AcWing 179. 八数码

https://www.acwing.com/problem/content/181/
请添加图片描述

import heapq

def f(lis):
    res = 0
    for i in range(9):
        if lis[i]=='x':
            continue
        res += abs(i//3-(int(lis[i])-1)//3)+abs(i%3-((int(lis[i])-1)%3))
    return res

def bfs():
    dist = {}
    # 操作actions,上一个字符串
    prev = {}
    hp = []
    heapq.heappush(hp,(f(start),start))
    dist[tuple(start)] = 0
    while hp:
        lis = heapq.heappop(hp)[1]
        if lis==end:
            break
        idx = lis.index('x')
        x,y = idx//3,idx%3
        pre_lis = lis[:]
        t_pre_lis = tuple(pre_lis)
        for i in range(4):
            x1,y1 = x+xdis[i],y+ydis[i]
            if x1<0 or y1<0 or x1>=3 or y1>=3:
                continue
            lis[x*3+y],lis[x1*3+y1] = lis[x1*3+y1],lis[x*3+y]
            t_lis = tuple(lis)
            if t_lis not in dist or dist[t_lis]>dist[t_pre_lis]+1:
                dist[t_lis]=dist[t_pre_lis]+1
                prev[t_lis] = (actions[i],t_pre_lis)
                heapq.heappush(hp,(dist[t_lis]+f(lis),lis[:]))
            lis[x*3+y],lis[x1*3+y1] = lis[x1*3+y1],lis[x*3+y]
    res = ''
    t_start = tuple(start)
    t_end = tuple(end)
    while t_start!=t_end:
        res = prev[t_end][0]+res
        t_end = prev[t_end][1]
    return res
        
actions = "urdl"
xdis = [-1,1,0,0]
ydis = [0,0,-1,1]


start = input().split()
end = list('12345678x')

cnt = 0
idx = start.index('x')
s = start[:idx]+start[idx+1:]
for i in range(8):
    for j in range(i+1,8):
        if s[i]>s[j]:
            cnt += 1
if cnt%2!=0:
    print('unsolvable')
else:
    print(bfs())
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值