Problem:


Score : 400 points

Problem Statement

Takahashi has a maze, which is a grid of H \times W squares with H horizontal rows and W vertical columns.

The square at the i-th row from the top and the j-th column is a "wall" square if S_{ij} is #, and a "road" square if S_{ij} is ..

From a road square, you can move to a horizontally or vertically adjacent road square.

You cannot move out of the maze, move to a wall square, or move diagonally.

Takahashi will choose a starting square and a goal square, which can be any road squares, and give the maze to Aoki.

Aoki will then travel from the starting square to the goal square, in the minimum number of moves required.

In this situation, find the maximum possible number of moves Aoki has to make.

Constraints

1 \leq H,W \leq 20

S_{ij} is . or #.

S contains at least two occurrences of ..

Any road square can be reached from any road square in zero or more moves.

Input

Input is given from Standard Input in the following format:

H W
S_{11}...S_{1W}
:
S_{H1}...S_{HW}

Output

Print the maximum possible number of moves Aoki has to make.

Sample Input 1

3 3
...
...
...

Sample Output 1

4

If Takahashi chooses the top-left square as the starting square and the bottom-right square as the goal square, Aoki has to make four moves.

Sample Input 2

3 5
...#.
.#.#.
.#...

Sample Output 2

10

If Takahashi chooses the bottom-left square as the starting square and the top-right square as the goal square, Aoki has to make ten moves.



Sample input:
3 3
...
...
...


Sample output:
4

Submission status: Accepted

Solution code:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
 
import numpy as np
from heapq import heappop, heappush
 
H,W = map(int,readline().split())
grid = np.full((H+2,W+2),b'#',dtype='S1')
grid[1:-1,1:-1] = np.frombuffer(read(),'S1').reshape(H,-1)[:,:W]
INF = 400
def shortest(grid, start, cost=0):
    dist = np.array([[INF for _ in range(W+2)] for _ in range(H+2)])
    dx = [-1, 0, 1, 0]
    dy = [0, 1, 0, -1]
    st = [(cost, start)]
    dist[start[0]][start[1]]=0
    while(st):
        c, [sx, sy] = heappop(st)
        for a, b in zip(dx, dy):
            x = sx + a
            y = sy + b
            if grid[x][y]==b'#':
              continue
            dxy = dist[sx][sy] + 1
            if dist[x][y] <= dxy:
                continue
            dist[x][y] = dxy
            heappush(st, (dist[x][y], [x, y]))
    return dist

m=0
for i in range(1,H+1):
  for j in range(1,W+1):
    if grid[i,j]==b'#':
      continue
    res=shortest(grid, [i,j], cost=0)[1:-1,1:-1]
    res[res==400]=0
    tm=np.max(res)
    if m < tm:
      m=tm
print(m)

Submission status: Accepted

Solution code:
from collections import deque
INF = 10 ** 9

class Edge:
	def __init__(self, t, w):
		self.t = t
		self.w = w

def around(i, j, H, W):
	if H == 1:
		if j == 0:
			ans = [(i, j+1)]
		elif j == W - 1:
			ans = [(i, j-1)]
		else:
			ans = [(i, j-1), (i, j+1)]
	elif W == 1:
		if i == 0:
			ans = [(i+1, j)]
		elif i == H - 1:
			ans = [(i-1, j)]
		else:
			ans = [(i-1, j), (i+1, j)]
	else:
		if i == 0:
			if j == 0:
				ans = [(i, j+1), (i+1, j)]
			elif j == W-1:
				ans = [(i, j-1), (i+1, j)]
			else:
				ans = [(i, j-1), (i, j+1), (i+1, j)]
		elif i == H - 1:
			if j == 0:
				ans = [(i-1, j), (i, j+1)]
			elif j == W-1:
				ans = [(i-1, j), (i, j-1)]
			else:
				ans = [(i-1, j), (i, j-1), (i, j+1)]
		else:
			if j == 0:
				ans = [(i-1, j), (i, j+1), (i+1, j)]
			elif j == W-1:
				ans = [(i-1, j), (i, j-1), (i+1, j)]
			else:
				ans = [(i-1, j), (i, j-1), (i, j+1), (i+1, j)]
	return ans

def bfs(s):
	d = [INF for _ in range(H*W)]
	Q = deque()
	Q.append(s)
	d[s] = 0
	while len(Q) > 0:
		u = Q.popleft()
		for e in G[u]:
			if d[e.t] == INF:
				d[e.t] = d[u] + e.w
				Q.append(e.t)
	return d

def solve(s):
	d = bfs(s)
	maxv = 0
	tgt = 0
	for i in range(W*H):
		if d[i] == INF:
			continue
		if maxv < d[i]:
			maxv = d[i]
			tgt = i
	d = bfs(tgt)
	maxv = 0
	for i in range(W*H):
		if d[i] == INF:
			continue
		maxv = max(maxv, d[i])
	return maxv

if __name__ == "__main__":
	H, W = map(int, input().split())
	S = [[0 for j in range(W)] for i in range(H)]
	# print(S)
	for i in range(H):
		s = input()
		for j in range(W):
			if s[j] == "#":
				S[i][j] = 1
	# print(S)
	G = [[] for _ in range(H*W)]
	for i in range(H):
		for j in range(W):
			if S[i][j] != 1:
				for (k, l) in around(i, j, H, W):
					if S[k][l] != 1:
						G[i*W + j].append(Edge(k*W + l, 1))
						G[k*W + l].append(Edge(i*W + j, 1))

	ans = 0
	for i in range(H):
		for j in range(W):
			if S[i][j] != 1:
				v = solve(i*W + j)
				ans = max(ans, v)
	print(ans)

Submission status: Accepted

Solution code:
a, b = map(int, input().split())
l = []
m = 0
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]

for _ in range(a):
    l.append(input())

for x in range(a):
    for y in range(b):
        if l[x][y] == '#':
            continue

        q = []
        cq = [0]
        l2 = [[0] * b for _ in range(a)]
        s, t = x, y
        l2[s][t] = 1

        while True:
            chk = 0

            for z in range(4):
                if s + dx[z] >= 0 and s + dx[z] < a and t + dy[z] >= 0 and t + dy[z] < b and l[s + dx[z]][t + dy[z]] == '.' and l2[s + dx[z]][t + dy[z]] == 0:
                    q.append([s + dx[z], t + dy[z]])
                    l2[s + dx[z]][t + dy[z]] = cq[0] + 1
                    cq.append(cq[0] + 1)
                    chk = 1

            if len(q) == 0:
                break
            
            if chk == 1 and cq[0] + 1 > m:
                m = cq[0] + 1

            s, t = q[0][0], q[0][1]
            q.pop(0)
            cq.pop(0)
            
print(m)

Submission status: Accepted

Solution code:
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import floyd_warshall
import numpy as np
H, W = map(int, input().split())
S = []
for h in range(H):
    Sh = list(input())
    S.append(Sh)
G = [[0 for _ in range(H*W)] for _ in range(H*W)]
for h in range(H):
    for w in range(W):
        if S[h][w] == '.':
            if h > 0 and S[h-1][w] == '.':
                G[h * W + w][(h - 1) * W + w] = 1
                G[(h - 1) * W + w][h * W + w] = 1
            if w > 0 and S[h][w-1] == '.':
                G[h * W + w][h * W + (w - 1)] = 1
                G[h * W + (w - 1)][h * W + w] = 1
            if h < H - 1 and S[h+1][w] == '.':
                G[h * W + w][(h + 1) * W + w] = 1
                G[(h + 1) * W + w][h * W + w] = 1
            if w < W - 1 and S[h][w+1] == '.':
                G[h * W + w][h * W + (w + 1)] = 1
                G[h * W + (w + 1)][h * W + w] = 1
graph = csr_matrix(G)
dist_matrix = floyd_warshall(csgraph=graph, directed=False)
max_dist = 0
for i in range(H * W):
    for j in range(H * W):
        d = dist_matrix[i][j]
        if d != np.inf and d > max_dist:
            max_dist = d
print(int(max_dist))

Submission status: Accepted

Solution code:
import copy
import queue

H,W = map(int, input().split())
def check(x,y):
    global W,H
    if x<0 or y<0 or x>=W or y>=H:
        return False
    return True

m = []
visit = []
for _ in range(H):
    S = list(input())
    m.append(S)
    l = [-1]*W
    visit.append(l)

visit_copy = copy.deepcopy(visit)
max = 0

for i in range(H):
    for j in range(W):
        sy = i
        sx = j
        q = queue.Queue()
        visit[sy][sx] = 0
        q.put([sy,sx])
        while not (q.empty()):
            y,x = q.get()
            if m[y][x]=="#":
                continue

            if check(x+1,y)==True:
                if visit[y][x+1]==-1 and m[y][x+1]==".":  
                    visit[y][x+1] = visit[y][x] + 1
                    if visit[y][x+1] > max:
                        max = visit[y][x+1]

                    q.put([y,x+1])
            if check(x,y+1)==True:
                if visit[y+1][x]==-1 and m[y+1][x]==".":  
                    visit[y+1][x] = visit[y][x] + 1
                    if visit[y+1][x] > max:
                        max = visit[y+1][x]

                    q.put([y+1,x])
            if check(x,y-1)==True:
                if visit[y-1][x]==-1 and m[y-1][x]==".":  
                    visit[y-1][x] = visit[y][x] + 1
                    if visit[y-1][x] > max:
                        max = visit[y-1][x]

                    q.put([y-1,x])
            if check(x-1,y)==True:
                if visit[y][x-1]==-1 and m[y][x-1]==".":  
                    visit[y][x-1] = visit[y][x] + 1
                    if visit[y][x-1] > max:
                        max = visit[y][x-1]

                    q.put([y,x-1])
        visit = copy.deepcopy(visit_copy)

print(max)

Submission status: Accepted

Solution code:
h, w = map(int, input().split())
s = [list(input()) for _ in range(h)]
visited = [[0 for _ in range(w)] for _ in range(h)]
disList = [[[[0 for _ in range(w)] for _ in range(h)] for _ in range(w)] for _ in range(h)]
# print(s)
for i in range(h):
    for j in range(w):
        if s[i][j] == "#":
            visited[i][j] = 1
import copy

ans = 0
for i in range(h):
    for j in range(w):
        nowdis = 0
        now = 0
        next_point = [[i, j, nowdis]]
        thisVisited = copy.deepcopy(visited)
        thisVisited[i][j] = 1
        if s[i][j] == "#":
            continue

        while now < len(next_point):
            nowi = next_point[now][0]
            nowj = next_point[now][1]
            nowdis = next_point[now][2]
            disList[i][j][nowi][nowj] = nowdis

            if nowi != 0:
                if thisVisited[nowi - 1][nowj] == 0:
                    next_point.append([nowi - 1, nowj, nowdis + 1])
                    thisVisited[nowi - 1][nowj] = 1

            if nowi != h - 1:
                if thisVisited[nowi + 1][nowj] == 0:
                    next_point.append([nowi + 1, nowj, nowdis + 1])
                    thisVisited[nowi + 1][nowj] = 1

            if nowj != w - 1:
                if thisVisited[nowi][nowj + 1] == 0:
                    next_point.append([nowi, nowj + 1, nowdis + 1])
                    thisVisited[nowi][nowj + 1] = 1

            if nowj != 0:
                if thisVisited[nowi][nowj - 1] == 0:
                    next_point.append([nowi, nowj - 1, nowdis + 1])
                    thisVisited[nowi][nowj - 1] = 1
            now += 1

# print(disList)
ans = 0
for i in disList:
    for j in i:
        for k in j:
            # print(k)
            ans = max(ans, max(k))

print(ans)

Submission status: Accepted

Solution code:
import numpy as np
from scipy.sparse.csgraph import floyd_warshall
i8 = np.int64
i4 = np.int32
dot = 46

stdin = open(0).read().split(sep='\n', maxsplit=1)
H, W = map(int, stdin[0].split())
s = np.frombuffer(np.array(stdin[1]), dtype=i4).reshape(H, W+1)
s = np.vstack((s, np.zeros(W + 1, i4)))
g = np.zeros((H * W, H * W), i8)
for i in range(H):
    for j in range(W):
        if s[i, j] == dot:
            if s[i, j + 1] == dot:
                g[W * i + j, W * i + j + 1] = 1
                g[W * i + j + 1, W * i + j] = 1
            if s[i + 1, j] == dot:
                g[W * i + j, W * (i + 1) + j] = 1
                g[W * (i + 1) + j, W * i + j] = 1

dist_matrix = floyd_warshall(g)
print(int(np.max(dist_matrix[dist_matrix < 1000])))

Submission status: Accepted

Solution code:
from collections import deque
INF = -1
H, W = map(int, input().split())
S = [input() for _ in range(H)]

dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

answer = 0
for y in range(H):
    for x in range(W):
        if S[y][x] == '#':
            continue
        else:
            # 対象の(x, y)を元に一番遠いところまで求める
            queue = deque([[y, x]])
            memo = [[INF] * W for _ in range(H)]

            memo[y][x] = 0
            while len(queue) > 0:
                myx = queue.pop()
                for i in range(4):
                    if myx[0] + dy[i] >= 0 and myx[0] + dy[i] < H:
                        if myx[1] + dx[i] >= 0 and myx[1] + dx[i] < W:
                            if memo[myx[0] + dy[i]][myx[1] + dx[i]] == INF:
                                if S[myx[0] + dy[i]][myx[1] + dx[i]] == ".":
                                    memo[myx[0] + dy[i]][myx[1] + dx[i]] = memo[myx[0]][myx[1]] + 1
                                    queue.appendleft([myx[0] + dy[i], myx[1] + dx[i]])
            for i in range(H):
                answer = max(answer, max(memo[i]))
print(answer)

Submission status: Accepted

Solution code:
from collections import deque

def astar(start, S, H, W):
  if S[start[0]][start[1]] == '#':
    return -1
  else:
    INF = 10**9
    D = [[INF]*W for h in range(H)]
    D[start[0]][start[1]] = 0
    next_node = deque([start])
    max_d = 0
    while next_node:
      now_y, now_x = next_node.popleft()
      d = D[now_y][now_x]
      for x, y in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
        if now_y+y<0 or now_y+y>=H or now_x+x<0 or now_x+x>=W:
          continue
        if S[now_y+y][now_x+x] == '.':
          if D[now_y+y][now_x+x] > d + 1:
            D[now_y+y][now_x+x] = D[now_y][now_x] + 1
            max_d = max(max_d, D[now_y+y][now_x+x])
            next_node.append([now_y+y, now_x+x])
    
    return max_d

H, W = map(int, input().split())
nodes = []
for h in range(H):
  for w in range(W):
    nodes.append([h, w])

S = []
for h in range(H):
  S.append(list(input()))

ans = 0
for start in nodes:
  ans = max(ans, astar(start, S, H, W))

print(ans)

Submission status: Accepted

Solution code:
def solve():
    from collections import deque
    from sys import stdin
    f_i = stdin
    
    H, W = map(int, f_i.readline().split())
    
    maze = '#' * (W + 2)
    for i in range(H):
        line = f_i.readline().rstrip()
        maze += '#' + line + '#'
    maze += '#' * (W + 2)
    
    move = (1, -1, W + 2, -W - 2)
    
    counts = []
    starts = (i for i in range(len(maze)) if maze[i] == '.')
    for start in starts:
        unvisited = [True] * len(maze)
        unvisited[start] = False
        
        q = deque([(start, 0)])
        while q:
            pos, cnt = q.popleft()
            
            for mv in move:
                next_pos = pos + mv
                if maze[next_pos] == '.' and unvisited[next_pos]:
                    q.append((next_pos, cnt + 1))
                    unvisited[next_pos] = False
            
            counts.append(cnt)
    
    print(max(counts))

solve()

Submission status: Accepted

Solution code:
from collections import deque
H, W = map(int, input().split())
S = [input() for _ in range(H)]
def bfs(s, t):
    dist = [[None] * W for _ in range(H)]
    que = deque([(s, t)])
    dist[s][t] = 0
    while que:
        u, v = que.popleft()
        d = dist[u][v]
        G = []
        if u > 0 and S[u-1][v] == ".":
            G.append((u-1, v))
        if u < H - 1 and S[u+1][v] == ".":
            G.append((u+1, v))
        if v > 0 and S[u][v-1] == ".":
            G.append((u, v-1))
        if v < W - 1 and S[u][v+1] == ".":
            G.append((u, v+1))
        for w, x in G:
            if dist[w][x] is None:
                dist[w][x] = d + 1
                que.append((w, x))
    return max(d if d is not None else 0 for di in dist for d in di)

print(max(bfs(i, j) for i in range(H) for j in range(W) if S[i][j] == "."))

Submission status: Accepted

Solution code:
H, W = map(int, input().split())

S = [list(input()) for _ in range(H)]

check = [[False]*W for _ in range(H)]

res = 0


for i in range(H):
    for j in range(W):
        if S[i][j] == "#":
            continue

        #if check[i][j]:
        #    continue

        mc = [[-1]*W for _ in range(H)]
        mc[i][j] = 0

        q = [(i, j)]
        #first = True
        while q:
            y, x = q.pop(0)
            for a, b in [(-1,0), (0,-1), (0,1), (1,0)]:
                if y+a < 0 or y+a >= H or x+b < 0 or x+b >= W:
                    continue

                if S[y+a][x+b] == "#":
                    continue


                if mc[y+a][x+b] == -1 or mc[y+a][x+b] > mc[y][x]+1:
                    mc[y+a][x+b] = mc[y][x]+1

                    res = max(res, mc[y+a][x+b])
                    q.append([y+a, x+b])

                    #if not first:
                        #check[y][x] = True
            #first = False

"""
for row in check:
    s = ""
    for x in row:
        if x:
            s += "#"
        else:
            s += "."
    print(s)
"""

print(res)

Submission status: Accepted

Solution code:
from collections import deque


H, W = map(int, input().split())
S = [list(input()) for _ in range(H)]

INF = 10 ** 6
visited = [[10 ** 6] * W for _ in range(H)]
dy = [-1, 1, 0, 0]
dx = [0, 0, -1, 1]


def bfs(y, x):
    q = deque()
    q.append((y, x))

    while len(q):
        y, x = q.popleft()

        for i in range(4):
            ny = y + dy[i]
            nx = x + dx[i]

            if (0 <= ny < H and 0 <= nx < W and
                visited[ny][nx] == INF and S[ny][nx] != '#'):

                q.append((ny, nx))
                visited[ny][nx] = visited[y][x] + 1

ans = 0
for y in range(H):
    for x in range(W):
        if S[y][x] != "#":
            visited = [[10 ** 6] * W for _ in range(H)]
            visited[y][x] = 0
            bfs(y, x)
            for i in range(H):
                for j in range(W):
                    if visited[i][j] != INF:
                        ans = max(ans, visited[i][j])

print(ans)

Submission status: Accepted

Solution code:
# coding: utf-8
import re
import math
from collections import deque
#import numpy as np


#main
H,W=map(int,input().split())
S=[[] for a in range(H)]
for a in range(H):
    s=input()
    for b in s:
        S[a].append(b)
ans=0
for i in range(H):
    for j in range(W):
        if(S[i][j]=='#'):continue
        cost=[[-1 for b in range(W)] for a in range(H)]
        cost[i][j]=0
        Q=deque([])
        Q.append([i,j])
        
        while len(Q)>0:
            now=Q.popleft()
            dx=[-1,0,1,0]
            dy=[0,1,0,-1]
            for a in range(4):
                x=now[1]+dx[a]
                y=now[0]+dy[a]
                if(x>=0 and x<W and y>=0 and y<H and S[y][x]=='.' and cost[y][x]==-1):
                    cost[y][x]=cost[now[0]][now[1]]+1
                    Q.append([y,x])
        for b in range(H):
            for a in range(W):
                ans=max(ans,cost[b][a])
        
print(ans)

Submission status: Accepted

Solution code:
from collections import deque

H ,W = map(int, input().split())
maze = []
for h in range(H):
    maze.append([s for s in input()])

dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

def bfs_maze(sx,sy):
    que = deque([])
    d = [[float("inf")] * W for i in range(H)]
    que.append((sx,sy))
    d[sx][sy] = 0
    
    while que:
        p = que.popleft()
        for i in range(4):
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]
            
            if (0 <= nx < H) and (0 <= ny < W) and (maze[nx][ny] != "#") and (d[nx][ny] == float("inf")):
                que.append((nx, ny))
                d[nx][ny] = d[p[0]][p[1]] + 1

    return d

max_d = 0
for w in range(W):
    for h in range(H):
        if maze[h][w] == ".":
            res = bfs_maze(h,w)
            for i in res:
                for j in i:
                    if j !=float("inf") and max_d < j:
                        max_d = j
print(max_d)

Submission status: Accepted

Solution code:
from itertools import product
from collections import defaultdict

h,w=list(map(int,input().split()))
maze=[list(input()) for _ in range(h)]
edges=defaultdict(list)
def neibors(x,y):
    return ((i,j)
     for i,j in [(x,y-1),(x,y+1),(x-1,y),(x+1,y)] 
            if 0<=i and i<h and 0<=j and j<w
     )
for x,y in product(range(h),range(w)):
    if maze[x][y]=='#':
        continue
    for adjx,adjy in neibors(x,y):
        if maze[adjx][adjy]=='.':
            edges[(x,y)].append((adjx,adjy))
distance_pairs=[[] for _ in range(h*w+1)]
distance_pairs[0]=[(s,s) for s in edges]
distances=defaultdict(dict)
for s in edges:
    distances[s][s]=0

for k in range(h*w+1):
    for s,t in distance_pairs[k]:
        for new_t in edges[t]:
            if new_t in distances[s]:
                continue
            distance_pairs[k+1]+=[(s,new_t)]
            distances[s][new_t]=k+1
    
    if len(distance_pairs[k+1])==0:
        break
print(k)

Submission status: Accepted

Solution code:
from collections import deque
INF = 1e9
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]


def bfs(sy, sx):
    if wall[sy][sx]=="#":
        return 0
    que = deque()
    que.append((sy, sx))
    d[sy][sx] = 0
    m = 0
    while len(que) > 0:
        y, x = que.popleft()

        for i in range(4):
            ny = y+dy[i]
            nx = x+dx[i]
            if 0 <= ny and ny < h and 0 <= nx and nx < w and wall[ny][nx] != "#" and d[ny][nx] == INF:
                que.append((ny, nx))
                d[ny][nx] = d[y][x]+1
                m = max(d[ny][nx],m)
    return m


h, w = map(int, input().split())
wall = [list(input()) for _ in range(h)]

ans = 0
for i in range(h):
    for j in range(w):
        d = [[INF]*w for _ in range(h)]
        a = bfs(i, j)
        ans = max(ans, a)
print(ans)

Submission status: Accepted

Solution code:
H, W = map(int, input().split())
S    = [None] * H # S[h][w]
for h in range(H):
    S[h] = list(input())

# find temporary start
Q_start = []
for h in range(H):
    for w in range(W):
        if S[h][w] == '.':
            Q_start.append((h, w))

answer = 0

# find start
for h_goal, w_goal in Q_start:
    STEPs                 = [[-1 for w in range(W)] for h in range(H)] # STEPs[x][y]
    STEPs[h_goal][w_goal] = 0
    max_STEP              = 0

    Q = [(h_goal, w_goal)]
    while len(Q) > 0:
        Q_new = []
        for q in Q:
            step     = STEPs[q[0]][q[1]]
            max_STEP = max(max_STEP, step)
            for h, w in [(q[0]-1, q[1]), (q[0], q[1]-1), (q[0], q[1]+1), (q[0]+1, q[1])]:
                if (h < 0 or w < 0) or (h >= H or w >= W) or (STEPs[h][w] != -1) or S[h][w] != '.':
                    continue
                else:
                    STEPs[h][w] = step+1
                    Q_new.append((h, w))
        Q = Q_new
    answer = max(answer, max_STEP)

print(answer)

Submission status: Accepted

Solution code:
from collections import deque


# (sx, sy) から (gx, gy) への最短距離を求める
# 辿り着けないと INF
def bfs():
    # すべての点を -INF で初期化
    d = [[-float("inf")] * m for i in range(n)]

    # 移動4方向のベクトル
    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]



    # スタート地点をキューに入れ、その点の距離を0にする
    que = deque([])
    que.append((sx, sy))
    d[sx][sy] = 0

    # キューが空になるまでループ
    while que:
        # キューの先頭を取り出す
        p = que.popleft()
        # # 取り出してきた状態がゴールなら探索をやめる
        # if p[0] == gx and p[1] == gy:
        #     break
        # 移動4方向をループ
        for i in range(4):
            # 移動した後の点を (nx, ny) とする
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]

            # 移動が可能かの判定とすでに訪れたことがあるかの判定
            # d[nx][ny] != INF なら訪れたことがある
            if 0 <= nx < n and 0 <= ny < m and maze[nx][ny] != "#" and d[nx][ny] == -float("inf"):
                # 移動できるならキューに入れ、その点の距離を p からの距離 +1 で確定する
                que.append((nx, ny))
                d[nx][ny] = d[p[0]][p[1]] + 1

    #return d[gx]
    a = 0
    for i in range(n):
        for j in range(m):
            a = max(d[i][j],a)
    return a

    #return max(d)


n, m = map(int, input().split())
maze = [list(input()) for i in range(n)]
ans = 0
for sx in range(n):
    for sy in range(m):
        if maze[sx][sy] == '.':
            ans = max(ans, bfs())
        # for gx in range(n):
        #     for gy in range(m):
        #         if maze[sx][sy] == '.' and maze[gx][gy] == '.' and not (sx == gx and sy == gy):
        #             if bfs() != float('inf'):
        #                 ans = max(ans,bfs())
print(ans)

Submission status: Accepted

Solution code:
#coding:utf-8
import sys

sys.setrecursionlimit(10**6)
write = sys.stdout.write
dbg = lambda *something : print(*something) if DEBUG else 0
DEBUG = True

def index(a,b):
    return str(min(a,b)) + "," +  str(max(a, b))

def main(given = sys.stdin.readline):
    input = lambda : given().rstrip()
    LMIIS = lambda : list(map(int,input().split()))
    II = lambda : int(input())
    XLMIIS = lambda x : [LMIIS() for _ in range(x)]


    H, W = LMIIS()
    s = [[] for _ in range(H+2)]
    s[0] = "#" * (W+2)
    s[H+1] = "#" * (W+2)
    for i in range(1, H+1):
        s[i] = "#" + input() + "#"

    g = [[] for _ in range(H*W)]
    for i in range(1, H+1):
        for j in range(1, W+1):
            if s[i][j] == "#":
                g[(i-1)*W + j -1] = [-1]
            else:
                if s[i-1][j] == ".":
                    g[(i-1)*W + j -1].append((i-2)*W + j - 1)
                if s[i][j-1] == ".":
                    g[(i-1)*W + j -1].append((i-1)*W + j - 2)
                if s[i+1][j] == ".":
                    g[(i-1)*W + j -1].append(i*W + j - 1)
                if s[i][j+1] == ".":
                    g[(i-1)*W + j -1].append((i-1)*W + j)


    ans = 0
    for i in range(H*W):
        if g[i][0] == -1:
            continue
        m = [-1] * (H*W)
        m[i] = 0
        q = g[i]
        l = 1
        while len(q) > 0:
            tmp = []
            for a in q:
                m[a] = l
                for b in g[a]:
                    if m[b] == -1 and not b in tmp:
                        tmp.append(b)
                    else:
                        m[b] = min(l+1, m[b])

            l += 1
            q = tmp[:]

        ans = max(ans, max(m))
    print(ans)




if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10**9)
input = lambda: sys.stdin.readline().rstrip()
inpl = lambda: list(map(int,input().split()))

from heapq import heappop, heappush
def dijkstra(start, goal, N, edges,
             get_route = False,
             start_distance=0,
             plus_func=lambda D,d: D+d):
    '''
    goal: int or list or set
    edges: list or dict
        edges[x] = {(y0, distance0),...}
    '''
    q = [(start_distance, start)]
    done = set()
    if isinstance(goal, int):
        goal_set = {goal}
    else:
        goal_set = set(goal)
    ret = [None]*N
    predecessor = [None]*N
    minimum = [None]*N

    while q:
        D, x = heappop(q)
        if x in done:
            continue
        elif x in goal_set:
            ret[x] = D
            goal_set.remove(x)
            if len(goal_set) == 0:
                # return ret
                break
        done.add(x)
        for y, d in edges[x]:
            if not y in done:
                m = minimum[y]
                p = plus_func(D, d)
                if m is None or m > p:
                    heappush(q, (p, y))
                    minimum[y] = p
                    predecessor[y] = x
    return D
    # if get_route:
    #     return ret, predecessor
    # else:
    #     return ret

H, W = inpl()
S = [input() for _ in range(H)]
N = H*W
edges = [set() for _ in range(N)]
dots = []
i = -1
for h in range(H):
    for w in range(W):
        i += 1
        if S[h][w] != '.':
            continue
        dots.append(i)
        if w < W-1 and S[h][w+1] == '.':
            edges[i].add((i+1,1))
            edges[i+1].add((i,1))
        if h < H-1 and S[h+1][w] == '.':
            edges[i].add((i+W,1))
            edges[i+W].add((i,1))
M = len(dots)
ans = 0
for m in range(M-1):
    s = dots[-1]
    dots.pop()
    d = dijkstra(s, dots, N, edges)
    if d > ans:
        ans = d
print(ans)

Submission status: Accepted

Solution code:
import sys
from math import factorial
from fractions import Fraction
import heapq, bisect, fractions
import math
import itertools
sys.setrecursionlimit(10 ** 5 + 10)
INF = 10**9 +5
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
MOD = 10**9 + 7

h, w = MAP()
maze = [[]for i in range(h)]
for i in range(h):
    si = list(input())
    maze[i] = si

ans = []
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
def dfs(sx, sy):
    q = []
    d = [[INF]*w for i in range(h)]
    heapq.heappush(q, [0, sx, sy])
    d[sx][sy] = 0
    res = 0
    while len(q) >0:
        p = heapq.heappop(q)
        for i in range(4):
            nx = p[1] + dx[i]
            ny = p[2] + dy[i]
            if 0<=nx<h and 0<=ny<w and maze[nx][ny] == '.' and d[nx][ny] == INF:
                heapq.heappush(q, [d[p[1]][p[2]] + 1, nx, ny])
                d[nx][ny] = d[p[1]][p[2]] + 1
                if d[nx][ny] > res:
                    res = d[nx][ny]
    return res

for i in range(h):
    for j in range(w):
        if maze[i][j] == '.':
            ans.append(dfs(i, j))

print(max(ans))

Submission status: Accepted

Solution code:
from collections import deque

H, W = map(int, input().split())
S = [0]*H
for i in range(H):
    S[i] = input()
# print(H, W, S)


def is_inside(w, h, W, H):
    if w >= 0 and w < W and h >= 0 and h < H:
        return True
    return False

def solve(sh, sw):
    T = [[0]* W for h in range(H)]
    for i in range(H):
        for j in range(W):
            if S[i][j] == '#':
                T[i][j] = -1
    if T[sh][sw] == -1:
        return T
    V = deque([(sh, sw)])
    T[sh][sw] = -2
    while len(V) != 0:
        v = V.popleft()
        h = v[0]
        w = v[1]
        # print(h, w)
        t = T[h][w]
        if t == -2:
            t = 0
        if is_inside(h - 1, w, H, W):
            if T[h - 1][w] == 0:
                T[h - 1][w] = t + 1
                V.append((h - 1, w))
        if is_inside(h + 1, w, H, W):
            if T[h + 1][w] == 0:
                T[h + 1][w] = t + 1
                V.append((h + 1, w))
        if is_inside(h, w - 1, H, W):
            if T[h][w - 1] == 0:
                T[h][w - 1] = t + 1
                V.append((h , w - 1))
        if is_inside(h, w + 1, H, W):
            if T[h][w + 1] == 0:
                T[h][w + 1] = t + 1
                V.append((h , w + 1))
    # print(sh, sw, T)
    return T


ans = 0

for h in range(H):
    for w in range(W):
        T = solve(h, w)
        distance = 0
        for i in range(H):
            for j in range(W):
                d = T[i][j]
                distance = max(distance, d)
        ans = max(distance, ans)

print(ans)

Submission status: Accepted

Solution code:
from collections import deque
h, w = map(int, input().split())

field = [[c for c in input().strip()] for _ in range(h)]

dir_x = [0, 1, 0, -1]
dir_y = [-1, 0, 1, 0]
ans = 0
# 全部のマスをスタートにしてチェックする
for i in range(h):
    for j in range(w):
        if field[i][j] == '#':
            continue

        field_flag = [[0 for _ in range(w)] for _ in range(h)]
        field_step = [[0 for _ in range(w)] for _ in range(h)]
        # スタート地点を入れる
        d = deque()
        d.append([i, j])
        while (d):
            y, x = d.popleft()
            field_flag[y][x] = 1  # スタート地点のフラグを入れる
            for xx, yy in zip(dir_x, dir_y):
                if xx+x in range(w) and yy+y in range(h):
                    if field[yy+y][xx+x] == '.' and field_flag[yy+y][xx+x] == 0:
                        field_flag[yy+y][xx+x] = 1  # チェック済
                        # そこへたどり着く最小歩数
                        field_step[yy + y][xx + x] = field_step[y][x] + 1
                        ans = max(ans, field_step[yy + y][xx + x])  # 答えの更新
                        d.append([yy+y, xx+x])

print(ans)