docs: def floyd_warshall(self):
          '''
          API:
              floyd_warshall(self)
          Description:
              Finds all pair shortest paths and stores it in a list of lists.
              This is possible if the graph does not have negative cycles. It will
              return a tuple with 3 elements. The first element indicates whether
              the graph has a negative cycle. It is true if the graph does not
              have a negative cycle, ie. distances found are valid shortest
              distances. The second element is a dictionary of shortest distances
              between nodes. Keys are tuple of node pairs ie. (i,j). The third
              element is a dictionary that helps to retrieve the shortest path
              between nodes. Then return value can be represented as (validity,
              distance, nextn) where nextn is the dictionary to retrieve paths.
              distance and nextn can be used as inputs to other methods to get
              shortest path between nodes.
          Pre:
              Arcs should have 'cost' attribute.
          Return:
              Returns (validity, distance, nextn). The distances are valid if
              validity is True.
          '''
          nl = self.get_node_list()
          el = self.get_edge_list()
          # initialize distance
          distance = {}
          for i in nl:
              for j in nl:
                  distance[(i,j)] = 'infinity'
          for i in nl:
              distance[(i,i)] = 0
          for e in el:
              distance[(e[0],e[1])] = self.get_edge_cost(e)
          # == end of distance initialization
          # initialize next
          nextn = {}
          for i in nl:
              for j in nl:
                  if i==j or distance[(i,j)]=='infinity':
                      nextn[(i,j)] = None
                  else:
                      nextn[(i,j)] = i
          # == end of next initialization
          # compute shortest distance
          for k in nl:
              for i in nl:
                  for j in nl:
                      if distance[(i,k)]=='infinity' or distance[(k,j)]=='infinity':
                          continue
                      elif distance[(i,j)]=='infinity':
                          distance[(i,j)] = distance[(i,k)] + distance[(k,j)]
                          nextn[(i,j)] = nextn[(k,j)]
                      elif distance[(i,j)] > distance[(i,k)] + distance[(k,j)]:
                          distance[(i,j)] = distance[(i,k)] + distance[(k,j)]
                          nextn[(i,j)] = nextn[(k,j)]
          # == end of compute shortest distance
          # check if graph has negative cycles
          for i in nl:
              if distance[(i,i)] < 0:
                  # shortest distances are not valid
                  # graph has negative cycle
                  return (False, distance, nextn)
          return (True, distance, nextn)