电路维修 (双端BFS)
这一题是双端BFS的应用,感觉y总直接掏这个出来讲,有点难了
- 这一题的难点首先不在双端队列,而是在对输入的理解,我们得把输入当做格子里的内容,而把定点当做我们进行遍历的依据,起点为(0,0),终点为(n,m)
- 当我们从起点开始宽搜时,我们只能往四个角的方向前进,而决定我们前进的代价当然就是有没有电线正好对角,如果有,那就是0,否则就是1。所以真正恶心人的就在这里的判断上了,我们得找出来要前进的方向那个格子里的电线是什么状态,这里要用点ix,iy数组
- 当解决了以上问题,才真正到了双端BFS的处理
-
首先判断从当前这个点出发能不能更新下一个点,如果能让它变短,那就可以更新。
-
如果可以更新,如果这次消耗为0,那么就添加到队列首部,如果消耗为1,那就放到队列尾部
from collections import deque
def isvalid(x,y):
if x<0 or x>n:
return False
if y<0 or y>m:
return False
return True
def isvalids(x,y):
if x<0 or x>=n:
return False
if y<0 or y>=m:
return False
return True
def bfs():
q=deque([])
q.append((0,0))
st=[[False for i in range(m+1)]for j in range(n+1)]
dist=[[1<<31 for i in range(m+1)]for j in range(n+1)]
dist[0][0]=0
dx=[-1,-1,1,1]
dy=[-1,1,1,-1]
ix=[-1,-1,0,0]
iy=[-1,0,0,-1]
sign="\\/\\/"
while q:
top=q.popleft()
x,y=top[0],top[1]
if x==n and y==m:
return dist[n][m]
if not st[x][y]:
st[x][y]=True
for i in range(4):
nx=x+dx[i]
ny=y+dy[i]
if isvalid(nx,ny):
signx=x+ix[i]
signy=y+iy[i]
if isvalids(signx,signy):
w=(adj[signx][signy]!=sign[i])
d=dist[x][y]+w
if d<=dist[nx][ny]:
dist[nx][ny]=d
if w==1:
q.append((nx,ny))
else:
q.appendleft((nx,ny))
return -1
t=int(input())
for _ in range(t):
n,m=map(int,input().split())
adj=[]
for i in range(n):
adj.append(list(input()))
if (n+m)&1:
print("NO SOLUTION")
else:
print(bfs())