// File: /workspace/github_cpp_makefile_star2_O2/Kei18[P]pibt/./src/graph/graph.cpp
// Function: Graph::getPath(Node*, Node*, std::vector<Node*, std::allocator<Node*>>&, int (*)(Node*, Node*))
Nodes Graph::getPath(Node* _s, Node* _g,
                     Nodes &prohibitedNodes, int (*dist) (Node*, Node*))
{
  bool prohibited = !prohibitedNodes.empty();
  Nodes path, C;
  std::string key;

  // ==== fast implementation ====
  if (regFlg && !prohibited) {
    key = getKey(_s, _g);
    auto itrK = knownPaths.find(key);
    if (itrK != knownPaths.end()) {  // known
      path = itrK->second->path;
      return path;
    }
  }
  // =============================

  int f;
  bool invalid = true;

  // prepare node open hashtable
  boost::heap::fibonacci_heap<Fib_AN> OPEN;
  std::unordered_map<int, boost::heap::fibonacci_heap<Fib_AN>::handle_type> SEARCHED;
  std::unordered_set<int> CLOSE;
  AN* n = new AN { _s, 0, dist(_s, _g), nullptr };
  auto handle = OPEN.push(Fib_AN(n));
  SEARCHED.emplace(n->v->getId(), handle);

  while (!OPEN.empty()) {
    // argmin
    n = OPEN.top().node;

    // check goal condition
    if (n->v == _g) {
      invalid = false;
      break;
    }

    // ==== fast implementation ====
    key = getKey(n->v, _g);
    auto itrK = knownPaths.find(key);
    if (itrK != knownPaths.end()) {  // known
      Nodes kPath = itrK->second->path;
      bool valid = true;
      if (prohibited) {
        for (auto v : kPath) {
          if (inArray(v, prohibitedNodes)) {
            valid = false;
            break;
          }
        }
      }
      if (valid) {
        for (int i = 1; i < kPath.size(); ++i) {
          n = new AN { kPath[i], 0, 0, n };
        }
        invalid = false;
        break;
      }
    }
    // =============================

    // update list
    OPEN.pop();
    CLOSE.emplace(n->v->getId());

    // search neighbor
    C = neighbor(n->v);

    for (auto m : C) {
      if (prohibited && inArray(m, prohibitedNodes)) continue;
      if (CLOSE.find(m->getId()) != CLOSE.end()) continue;
      f = n->g + 1 + dist(m, _g);

      // ==== fast implementation ====
      if (regFlg) {
        key = getKey(m, _g);
        auto itrK = knownPaths.find(key);
        if (itrK != knownPaths.end()) {
          f = n->g + 1 + itrK->second->path.size() - 1;
        }
      }
      // =============================

      auto itrS = SEARCHED.find(m->getId());
      if (itrS == SEARCHED.end()) {  // new node
        AN* l = new AN { m, n->g + 1, f, n };
        auto handle = OPEN.push(Fib_AN(l));
        SEARCHED.emplace(l->v->getId(), handle);
      } else {
        auto handle = itrS->second;
        AN* l = (*handle).node;
        if (l->f > f) {
          l->g = n->g + 1;
          l->f = f;
          l->p = n;
          OPEN.increase(handle);
        }
      }
    }
  }

  if (invalid) return path;

  // back tracking
  while (n != nullptr) {
    path.push_back(n->v);
    n = n->p;
  }
  std::reverse(path.begin(), path.end());

  // register path
  if (regFlg && !prohibited) registerPath(path);

  return path;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq %r9, 0x58(%rsp)
movq %rcx, %r14
movq %rdx, %rbx
movq %rsi, 0x8(%rsp)
movq (%r8), %rcx
movq %r8, 0x60(%rsp)
movq 0x8(%r8), %rdx
xorps %xmm0, %xmm0
andq $0x0, 0x10(%rdi)
movq %rdi, (%rsp)
movups %xmm0, (%rdi)
andq $0x0, 0x80(%rsp)
leaq 0xd0(%rsp), %rax
andq $0x0, -0x8(%rax)
movaps %xmm0, 0x70(%rsp)
movq %rax, -0x10(%rax)
movb $0x0, (%rax)
movq %rcx, 0x48(%rsp)
movq %rdx, 0x40(%rsp)
cmpq %rdx, %rcx
jne 0x165ec
movq 0x8(%rsp), %rax
cmpb $0x0, 0x9(%rax)
je 0x165ec
leaq 0xe0(%rsp), %rdi
movq %rbx, %rdx
movq %r14, %r12
movq %r14, %rcx
callq 0x16b0c
leaq 0xc0(%rsp), %r14
leaq 0xe0(%rsp), %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x6470
movq %r15, %rdi
callq 0x61d0
movq 0x8(%rsp), %rax
leaq 0x28(%rax), %rdi
movq %r14, %rsi
callq 0x17680
testq %rax, %rax
movq %r12, %r14
je 0x165ec
movq 0x28(%rax), %rsi
addq $0x10, %rsi
movq (%rsp), %rdi
callq 0x16f90
jmp 0x16a3f
leaq 0xa8(%rsp), %rax
xorps %xmm0, %xmm0
movaps %xmm0, -0x18(%rax)
andq $0x0, -0x8(%rax)
movq %rax, (%rax)
movq %rax, 0x8(%rax)
leaq 0x110(%rsp), %rax
movq %rax, -0x30(%rax)
pushq $0x1
popq %rdx
movq %rdx, -0x28(%rax)
movups %xmm0, -0x20(%rax)
movl $0x3f800000, %ecx       # imm = 0x3F800000
movl %ecx, -0x10(%rax)
movups %xmm0, -0x8(%rax)
leaq 0x150(%rsp), %rax
movq %rax, -0x30(%rax)
movq %rdx, -0x28(%rax)
movups %xmm0, -0x20(%rax)
movl %ecx, -0x10(%rax)
movups %xmm0, -0x8(%rax)
pushq $0x18
popq %rdi
callq 0x63b0
movq %rax, %rbp
movq %rbx, (%rax)
andl $0x0, 0x8(%rax)
movq %rbx, %rdi
movq %r14, %rsi
callq *0x58(%rsp)
movl %eax, 0xc(%rbp)
andq $0x0, 0x10(%rbp)
leaq 0x20(%rsp), %rsi
movq %rbp, (%rsi)
leaq 0x90(%rsp), %rdi
callq 0x1705a
leaq 0x118(%rsp), %rdx
movq %rax, (%rdx)
movq (%rbp), %rax
movl (%rax), %eax
leaq 0x20(%rsp), %rsi
movl %eax, (%rsi)
leaq 0xe0(%rsp), %rdi
callq 0x179ea
movq 0x8(%rsp), %rax
addq $0x28, %rax
movq %rax, 0x50(%rsp)
movb $0x1, %al
movl %eax, 0x14(%rsp)
leaq 0x20(%rsp), %r12
pushq $0x18
popq %r13
movq %r14, 0x18(%rsp)
cmpq $0x0, 0x90(%rsp)
je 0x169c5
leaq 0x90(%rsp), %rdi
callq 0x170d2
movq (%rax), %rbp
movq (%rbp), %rdx
cmpq %r14, %rdx
je 0x169de
movq %r12, %rdi
movq %r14, %rcx
callq 0x16b0c
leaq 0xc0(%rsp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6470
movq %r12, %rdi
callq 0x61d0
movq 0x50(%rsp), %rdi
movq %rbx, %rsi
callq 0x17680
testq %rax, %rax
je 0x167d2
movq 0x28(%rax), %rsi
addq $0x10, %rsi
movq %r12, %rdi
callq 0x15d3a
movq 0x40(%rsp), %rax
cmpq %rax, 0x48(%rsp)
je 0x16774
movq 0x20(%rsp), %rbx
movq 0x28(%rsp), %r14
cmpq %r14, %rbx
je 0x16774
movq (%rbx), %rdi
movq 0x60(%rsp), %rsi
callq 0x16ba9
addq $0x8, %rbx
testb %al, %al
je 0x16753
xorl %r14d, %r14d
xorl %ebx, %ebx
jmp 0x167bc
movq 0x20(%rsp), %rbx
movq 0x28(%rsp), %r14
subq %rbx, %r14
sarq $0x3, %r14
pushq $0x1
popq %r15
cmpq %r15, %r14
jbe 0x167ae
movq %r13, %rdi
callq 0x63b0
movq (%rbx,%r15,8), %rcx
movq %rcx, (%rax)
andq $0x0, 0x8(%rax)
movq %rbp, 0x10(%rax)
incq %r15
movq %rax, %rbp
jmp 0x16789
movb $0x1, %r14b
movl $0x0, 0x14(%rsp)
pushq $0x3
popq %rbx
movq %r12, %rdi
callq 0x990e
testb %r14b, %r14b
movq 0x18(%rsp), %r14
jne 0x169bd
leaq 0x90(%rsp), %rdi
callq 0x17102
movq (%rbp), %rax
movl (%rax), %eax
movl %eax, 0x20(%rsp)
leaq 0x120(%rsp), %rdi
movq %r12, %rsi
callq 0x18142
movq (%rbp), %rsi
addq $0x8, %rsi
movq %r12, %rdi
callq 0x15d3a
leaq 0x70(%rsp), %rdi
movq %r12, %rsi
callq 0x18466
movq %r12, %rdi
callq 0x990e
movq 0x70(%rsp), %r13
movq 0x78(%rsp), %rax
movq %rax, 0x88(%rsp)
cmpq 0x88(%rsp), %r13
je 0x169ad
movq (%r13), %r14
movq 0x40(%rsp), %rax
cmpq %rax, 0x48(%rsp)
je 0x1685f
movq %r14, %rdi
movq 0x60(%rsp), %rsi
callq 0x16ba9
testb %al, %al
jne 0x1687d
movl (%r14), %eax
movl %eax, 0x20(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x184b8
testq %rax, %rax
je 0x16883
addq $0x8, %r13
jmp 0x16830
movl 0x8(%rbp), %ebx
movq %r14, %rdi
movq 0x18(%rsp), %rsi
callq *0x58(%rsp)
addl %eax, %ebx
incl %ebx
movq 0x8(%rsp), %rax
cmpb $0x1, 0x9(%rax)
jne 0x168fc
movq %rbp, %r12
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %r14, %rdx
movq 0x18(%rsp), %rcx
callq 0x16b0c
leaq 0xc0(%rsp), %rbp
movq %rbp, %rdi
movq %r15, %rsi
callq 0x6470
movq %r15, %rdi
callq 0x61d0
movq 0x50(%rsp), %rdi
movq %rbp, %rsi
callq 0x17680
testq %rax, %rax
movq %r12, %rbp
je 0x168fc
movq 0x28(%rax), %rax
movq 0x18(%rax), %rbx
subq 0x10(%rax), %rbx
shrq $0x3, %rbx
addl 0x8(%rbp), %ebx
movl (%r14), %eax
movl %eax, 0x20(%rsp)
leaq 0xe0(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x184d6
testq %rax, %rax
je 0x1694c
movq 0x10(%rax), %rsi
movq 0x10(%rsi), %rax
cmpl %ebx, 0xc(%rax)
jle 0x1687d
movl 0x8(%rbp), %ecx
incl %ecx
movl %ecx, 0x8(%rax)
movl %ebx, 0xc(%rax)
movq %rbp, 0x10(%rax)
leaq 0x90(%rsp), %rdi
callq 0x1717c
jmp 0x1687d
pushq $0x18
popq %rdi
callq 0x63b0
movq %rax, %r15
movq %r14, (%rax)
movl 0x8(%rbp), %eax
incl %eax
movl %eax, 0x8(%r15)
movl %ebx, 0xc(%r15)
movq %rbp, 0x10(%r15)
movq %r15, 0x68(%rsp)
leaq 0x90(%rsp), %rdi
leaq 0x68(%rsp), %rbx
movq %rbx, %rsi
callq 0x1705a
movq %rax, 0x20(%rsp)
movq (%r15), %rax
movl (%rax), %eax
movl %eax, 0x68(%rsp)
leaq 0xe0(%rsp), %rdi
movq %rbx, %rsi
leaq 0x20(%rsp), %rdx
callq 0x179ea
jmp 0x1687d
xorl %ebx, %ebx
movq 0x18(%rsp), %r14
leaq 0x20(%rsp), %r12
pushq $0x18
popq %r13
testl %ebx, %ebx
je 0x166c5
testb $0x1, 0x14(%rsp)
je 0x169de
jmp 0x16a18
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x171da
movq 0x10(%rbp), %rbp
testq %rbp, %rbp
jne 0x169ce
movq (%rsp), %rax
movq (%rax), %rdi
movq 0x8(%rax), %rsi
callq 0x18697
movq 0x40(%rsp), %rax
cmpq %rax, 0x48(%rsp)
jne 0x16a18
movq 0x8(%rsp), %rax
cmpb $0x0, 0x9(%rax)
je 0x16a18
movq 0x8(%rsp), %rdi
movq (%rsp), %rsi
callq 0x16bd2
leaq 0x120(%rsp), %rdi
callq 0x174fe
leaq 0xe0(%rsp), %rdi
callq 0x175a6
leaq 0x90(%rsp), %rdi
callq 0x171f8
leaq 0xc0(%rsp), %rdi
callq 0x61d0
leaq 0x70(%rsp), %rdi
callq 0x990e
movq (%rsp), %rax
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x16a86
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
movq %rax, %rbx
pushq $0x18
popq %rsi
movq %rbp, %rdi
callq 0x63c0
jmp 0x16abd
jmp 0x16aba
movq %rax, %rbx
jmp 0x16ae4
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aba
jmp 0x16aa9
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x990e
jmp 0x16abd
jmp 0x16aba
movq %rax, %rbx
leaq 0x120(%rsp), %rdi
callq 0x174fe
leaq 0xe0(%rsp), %rdi
callq 0x175a6
leaq 0x90(%rsp), %rdi
callq 0x171f8
leaq 0xc0(%rsp), %rdi
callq 0x61d0
leaq 0x70(%rsp), %rdi
callq 0x990e
movq (%rsp), %rdi
callq 0x990e
movq %rbx, %rdi
callq 0x6650