'''
先用floyd算法全局求一遍所有点对的最短距离,找出每个点到其他点的最短距离的最大值,然后用每个节点的这个最大值
的最大值作为答案,再枚举每一对互相没有连接的点对,点对的两个端点对应的最大值是已经算出来的,两个最大值加上
两个点之间的距离作为新值,求所有的新值中的最小值,用这个最小值更新最终答案
'''
import math
class Floyd:
def __init__(self, edges, is_directed):
self.edges = edges[::]
self.is_directed = is_directed
# 返回所有点对的最短距离,用map表返回,key是(节点1,节点2),值是节点之间的最短距离, 出现负权环或者无向图负边情况返回None
def getMinDis(self):
pair2dis = {}
all_nodes = set()
for a, b, w in self.edges:
all_nodes.add(a)
all_nodes.add(b)
for node1 in all_nodes:
for node2 in all_nodes:
pair2dis[(node1, node2)] = 0x7fffffff
for a, b, w in self.edges:
pair2dis[(a, a)] = 0
pair2dis[(b, b)] = 0
pair2dis[(a, b)] = w
if not self.is_directed:
pair2dis[(b, a)] = w
for t in all_nodes:
for node1 in all_nodes:
for node2 in all_nodes:
new_dis = 0x7fffffff if pair2dis[(node1, t)] == 0x7fffffff or pair2dis[(t, node2)] == 0x7fffffff else pair2dis[(node1, t)] + pair2dis[(t, node2)]
pair2dis[(node1, node2)] = min(pair2dis[(node1, node2)], new_dis)
# 检查是否有无向图的负权边或者有向图的负权环
for node in all_nodes:
if pair2dis[(node, node)] < 0:
return None
return pair2dis
def dis(a1, b1, a2, b2):
return math.sqrt((a1-a2)**2 + (b1-b2)**2)
p = []
n = int(input())
for i in range(n):
a, b = map(int, input().split())
p.append((a, b))
grid = []
for i in range(n):
arr = input()
grid.append(arr)
edges = []
for i in range(n):
for j in range(i+1, n):
if grid[i][j] == '1':
edges.append((i, j, dis(p[i][0], p[i][1], p[j][0], p[j][1])))
algo = Floyd(edges, is_directed=False)
max_path_len = [0] * n # 每个点出发的最长路径长度
min_len = algo.getMinDis()
ans = 0x7fffffff
for (a, b), val in min_len.items():
if val != 0x7fffffff:
max_path_len[a] = max(max_path_len[a], val)
ans = max(max_path_len)
min_val = 0x7fffffff
for i in range(n):
for j in range(i+1, n):
if (i, j) not in min_len or min_len[(i, j)] == 0x7fffffff:
mid_w = dis( p[i][0], p[i][1], p[j][0], p[j][1] )
val = max_path_len[i] + mid_w + max_path_len[j]
min_val = min(min_val, val)
ans = max(ans, min_val)
print('{:.6f}'.format(ans))