Submission #47157

#TimeUsernameProblemLanguageResultExecution timeMemory
47157platypusJakarta Skyscrapers (APIO15_skyscraper)C++14
0 / 100
2 ms628 KiB
#include <cstdio> #include <cstdlib> #include <cmath> #include <climits> #include <cfloat> #include <cstring> #include <map> #include <utility> #include <set> #include <iostream> #include <memory> #include <string> #include <vector> #include <list> #include <algorithm> #include <functional> #include <sstream> #include <complex> #include <stack> #include <queue> #include <unordered_set> #include <unordered_map> #include <array> #include <cassert> #include <bitset> using namespace std; using LL = long long; //Vは比較可能な値にする template <typename V> class Graph { private: map<V, vector<pair<V, LL>>>edge; public: //from->toへcostの辺を張る void addEdge(V from, V to, LL cost) { edge[from].push_back(make_pair(to, cost)); } //v1とv2間にcostの辺を張る void addUndirectedEdge(V v1, V v2, LL cost) { edge[v1].push_back(make_pair(v2, cost)); edge[v2].push_back(make_pair(v1, cost)); } //最短を求める void dijkstra(V start, map<V, LL>&dist) { dist[start] = 0; priority_queue<pair<LL, V>, vector<pair<LL, V>>, greater<pair<LL, V>>>que; que.push(make_pair(0LL, start)); while (!que.empty()) { auto q = que.top(); que.pop(); V now = q.second; LL dis = q.first; if (dist[now] < dis) continue; for (auto e : edge[now]) { V nxt = e.first; LL cost = e.second; if (!dist.count(nxt) || dist[nxt] > dist[now] + cost) { dist[nxt] = dist[now] + cost; que.push(make_pair(dist[nxt], nxt)); } } } } }; int N, M; int mceil(int a, int b) { if (a == 0)return 0; return (a - 1) / b + 1; } int main(void) { cin >> N >> M; using P = pair<int, int>; map<P, vector<int>>mp; int st = -1; int enb = -1, enp = -1, enr = -1; for (int i = 0; i < M; ++i) { int b, p; cin >> b >> p; if (i == 0)st = b; if (i == 1) { enb = b; enp = p; enr = b % p; } int rem = b % p; mp[make_pair(p, rem)].push_back(b); } Graph<P>G; for (auto elm : mp) { int p = elm.first.first; int rem = elm.first.second; auto& v = elm.second; int len = mceil(N - rem, p); vector<LL>dist(len, INT_MAX); for (int x : v)dist[x / p] = 0; /*for (int i = 1; i < len; ++i) { dist[i] = min(dist[i - 1] + 1, dist[i]); } for (int i = len - 1; i > 0; --i) { dist[i - 1] = min(dist[i] + 1, dist[i - 1]); }*/ for (int i = 0; i < len; ++i) { if (dist[i] < INT_MAX)G.addEdge(P(0, i * p + rem), P(p, i * p + rem), dist[i]); G.addEdge(P(p, i * p + rem), P(0, i * p + rem), 0LL); } for (int i = 1; i < len; ++i) { G.addUndirectedEdge(P(p, (i - 1)*p + rem), P(p, i*p + rem), 1LL); } } int len = mceil(N - enr, enp); for (int i = 0; i < len; ++i) { if (abs(i - (enb / enp)) == 0) G.addEdge(P(0, i * enp + enr), P(N, i * enp + enr), abs(i - (enb / enp))); } map<P, LL> dist; G.dijkstra(P(0, st), dist); LL ans = LLONG_MAX; for (int i = 0; i < len; ++i) { if (abs(i - (enb / enp)) == 0) ans = min(ans, dist[P(N, i * enp + enr)]); } if (ans == LLONG_MAX) { cout << -1 << endl; } else { cout << ans << endl; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...