#define _GLIBCXX_DEBUG #include #include #include #include #include using namespace std; const int AC = 42, WA = 43; using ll = long long; struct Edge { int v; ll weight; }; // input edges struct PQ { ll d; int v; Edge *e; }; // distance and target bool operator>(const PQ &l, const PQ &r) { return l.d > r.d; } void dijkstra(vector> &edges, int s, int t) { vector dist(edges.size(), 1e13); priority_queue, greater> pq; dist[s] = 0; pq.push({0, s, nullptr}); while(!pq.empty()) { auto x = pq.top(); pq.pop(); if(x.v == t) break; // target reached if(x.d == dist[x.v]) { if(x.e) x.e->weight = 1e13; for(auto &e : edges[x.v]) if(dist[e.v] > x.d + e.weight) pq.push({dist[e.v] = x.d + e.weight, e.v, &e}); } } } int main(int arcg, const char *args[]) { std::ifstream in(args[1]); std::ifstream ans(args[2]); std::istream &out = cin; { string s; ans >> s; // the grammar has checked the validity of the input, // and whether it matches impossible or not if(s == "impossible") return AC; } // read submitted path cout << "READ OUTPUT" << endl; int k; cin >> k; vector path(k); set path_set; for(auto &x : path) cin >> x, path_set.insert(x); if(path_set.size() < k) { cout << "Found duplicate numbers in submitted path!\n"; return WA; } if(path.front() != 0) { cout << "Path should start at 0, found " << path.front() << endl; return WA; } if(path.back() != 1) { cout << "Path should end at 1, found " << path.back() << endl; return WA; } cout << "READ INPUT" << endl; int n, m; in >> n >> m; cerr << " N,M " << n << ' ' << m << endl; vector> g(n); int s = 0, t = 1; while(m--) { int u, v, c; in >> u >> v >> c; cerr << u << ' ' << v << ' ' << c << endl; g[u].push_back({v, c}); g[v].push_back({u, c}); } for(auto &x : path) if(x < 0 || x >= n) { cout << "Path contains out of range index " << x << ". There are only " << n << " vertices!" << endl; return WA; } cout << "DIJKSTRA" << endl; // set 'optimal' edges to 1e13 length dijkstra(g, t, -1); cout << "VERIFY OUTPUT" << endl; // check whether submitted path has good length for(auto it = path.begin(); it != prev(path.end()); ++it) { int cur = *it, nxt = *next(it); for(const auto &e : g[nxt]) if(e.v == cur) { if(e.weight >= 1e13) { cout << "The edge from " << cur << " to " << nxt << " is in the shortest direction to Amsterdam!" << endl; return WA; } goto end; } cout << "No edge from " << cur << " to " << nxt << " was found!" << endl; return WA; end:; } return AC; }