bool Graph::Node::reachableBy(Node *node, Node *term) { Stack stack; Node *pos; const int seq = graph->nextSequence(); stack.push(node); while (stack.getSize()) { pos = reinterpret_cast<Node *>(stack.pop().u.p); if (pos == this) return true; if (pos == term) continue; for (EdgeIterator ei = pos->outgoing(); !ei.end(); ei.next()) { if (ei.getType() == Edge::BACK || ei.getType() == Edge::DUMMY) continue; if (ei.getNode()->visit(seq)) stack.push(ei.getNode()); } } return pos == this; }
bool Graph::Node::reachableBy(const Node *node, const Node *term) const { std::stack<const Node *> stack; const Node *pos = NULL; const int seq = graph->nextSequence(); stack.push(node); while (!stack.empty()) { pos = stack.top(); stack.pop(); if (pos == this) return true; if (pos == term) continue; for (EdgeIterator ei = pos->outgoing(); !ei.end(); ei.next()) { if (ei.getType() == Edge::BACK || ei.getType() == Edge::DUMMY) continue; if (ei.getNode()->visit(seq)) stack.push(ei.getNode()); } } return pos == this; }
bool Graph::Node::detach(Graph::Node *node) { EdgeIterator ei = this->outgoing(); for (; !ei.end(); ei.next()) if (ei.getNode() == node) break; if (ei.end()) { ERROR("no such node attached\n"); return false; } delete ei.getEdge(); return true; }
// @dist is indexed by Node::tag, returns -1 if no path found int Graph::findLightestPathWeight(Node *a, Node *b, const std::vector<int> &weight) { std::vector<int> path(weight.size(), std::numeric_limits<int>::max()); std::list<Node *> nodeList; const int seq = nextSequence(); path[a->tag] = 0; for (Node *c = a; c && c != b;) { const int p = path[c->tag] + weight[c->tag]; for (EdgeIterator ei = c->outgoing(); !ei.end(); ei.next()) { Node *t = ei.getNode(); if (t->getSequence() < seq) { if (path[t->tag] == std::numeric_limits<int>::max()) nodeList.push_front(t); if (p < path[t->tag]) path[t->tag] = p; } } c->visit(seq); Node *next = NULL; for (std::list<Node *>::iterator n = nodeList.begin(); n != nodeList.end(); ++n) { if (!next || path[(*n)->tag] < path[next->tag]) next = *n; if ((*n) == c) { // erase visited n = nodeList.erase(n); --n; } } c = next; } if (path[b->tag] == std::numeric_limits<int>::max()) return -1; return path[b->tag]; }