/* * rainbowRoads_sjz.cpp * * Created on: Oct 4, 2017 * Author: zeil */ #include #include #include #include #include #include #include using namespace std; typedef int BadgeNum; typedef int EdgeNum; typedef int VertexNum; BadgeNum nB; VertexNum nV; EdgeNum nE; typedef set BadgeSet; bool insertRange (BadgeSet& bset, int low, int high) { int sz = bset.size(); bset.insert(2*low); bset.insert(2*high+1); bool changed = (sz != bset.size()); return changed; } struct Edge { VertexNum source; VertexNum dest; BadgeNum min; BadgeNum max; bool inQ; Edge (VertexNum asource, VertexNum adest, BadgeNum amin, BadgeNum amax) : source(asource), dest(adest), min(amin), max(amax), inQ(false) {} }; struct Vertex { list outEdges; int reached; Vertex() : outEdges(), reached(-1) {} }; Vertex* vertex; set extrema; ostream& operator<< (ostream& out, const BadgeSet& b) { out << '{'; for (int i: b) { if (i % 2 == 1) out << ".."; out << i / 2; if (i % 2 == 1) out << ", "; else out << ' '; } out << "}"; return out; } ostream& operator<< (ostream& out, const Edge& e) { out << e.source << "=>" << e.dest << " [" << e.min << ".." << e.max << "]"; return out; } bool propogateBadgeNumbers(VertexNum start, VertexNum stop, int badgeNum) { vertex[start].reached = badgeNum; list queue; for (Edge e: vertex[start].outEdges) { queue.push_back(e); e.inQ = true; } int qcnt = 0; while (!queue.empty()) { ++qcnt; Edge e = queue.front(); queue.pop_front(); e.inQ = false; // cerr << "edge: " << e << endl; int prop = vertex[e.source].reached; bool changed = false; if (badgeNum >= 2*e.min && badgeNum <= 2*e.max+1) { changed |= vertex[e.dest].reached != badgeNum; vertex[e.dest].reached = badgeNum; if (e.dest == stop) return true; //cerr << e.dest << " becomes " << vertex[e.dest].reached << endl; if (changed) { //cerr << e.dest << " has changed." << endl; for (Edge e2: vertex[e.dest].outEdges) { if (!e2.inQ) { queue.push_back(e2); e2.inQ = true; } } } } } return vertex[stop].reached == badgeNum; //cerr << "Queue visited " << qcnt << " times" << endl; } void printReached(vector passed) { int count = 0; auto it = passed.begin(); while ( it != passed.end()) { const int low = *it; auto it0 = it; ++it; while (it != passed.end() && (*it) % 2 == 0) { it0 = it; ++it; } while (it != passed.end() && (*it) % 2 == 1) { it0 = it; ++it; } int high = *it0; if (low <= high) { count += high/2 - low/2 + 1; } } cout << count << endl; } void solve (istream& in) { in >> nV >> nE >> nB; VertexNum start, stop; in >> start >> stop; start--; stop-- ; vertex = new Vertex[nV]; for (int i = 0; i < nE; ++i) { int d, s, mn, mx; in >> s >> d >> mn >> mx; s-- ; d-- ; mn-- ; mx-- ; vertex[s].outEdges.push_back(Edge(s, d, mn, mx)); extrema.insert(2*mn); extrema.insert(2*mx+1); } vector propogated; for (int badge: extrema) { if (propogateBadgeNumbers(start, stop, badge)) propogated.push_back(badge); } printReached(propogated); } int main (int argc, char** argv) { if (argc > 1) { ifstream in (argv[1]); solve(in); } else { solve (cin); } }