Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <assert.h>
- #include <bits/stdc++.h>
- using namespace std;
- #define dbg(...) logger(#__VA_ARGS__, __VA_ARGS__)
- template <typename... Args> void logger(string vars, Args &&... values)
- {
- cerr << vars << " = ";
- string delim = "";
- (..., (cerr << delim << values, delim = ", "));
- cerr << endl;
- }
- template <class T> using mpq = priority_queue<T, vector<T>, greater<T>>;
- using ll = long long;
- using pii = pair<int, int>;
- int h, w, n;
- int sx, sy, gx, gy;
- map<int, vector<int>> hm, vm;
- int vcnt = 0;
- map<ll, int> v2i;
- int get_id(int x, int y)
- {
- ll id = ll(x) << 32 + y;
- if (v2i.count(id))
- return v2i[id];
- v2i[id] = vcnt++;
- return v2i[id];
- }
- struct Edge {
- int v, next;
- } edges[3200003];
- int head[400003], ecnt = 0;
- void add_edge(int u, int v)
- {
- if (u == v)
- return;
- edges[ecnt] = {v, head[u]};
- head[u] = ecnt++;
- }
- vector<pii> direct_add(int x, int y)
- {
- vector<pii> ret;
- int id = get_id(x, y);
- if (hm.count(x)) {
- const auto &ys = hm[x];
- int ub = upper_bound(ys.begin(), ys.end(), y) - ys.begin();
- if (ub < ys.size() && ys[ub] - y >= 1) {
- int id1 = get_id(x, ys[ub] - 1), id2 = get_id(x, y);
- add_edge(id2, id1);
- ret.push_back({x, ys[ub] - 1});
- }
- if (ub > 0 && y - ys[ub - 1] >= 1) {
- int id1 = get_id(x, ys[ub - 1] + 1), id2 = get_id(x, y);
- add_edge(id2, id1);
- ret.push_back({x, ys[ub - 1] + 1});
- }
- }
- if (vm.count(y)) {
- const auto &xs = vm[y];
- int ub = upper_bound(xs.begin(), xs.end(), x) - xs.begin();
- if (ub < xs.size() && xs[ub] - x >= 1) {
- int id1 = get_id(xs[ub] - 1, y), id2 = get_id(x, y);
- add_edge(id2, id1);
- ret.push_back({xs[ub] - 1, y});
- }
- if (ub > 0 && x - xs[ub - 1] >= 1) {
- int id1 = get_id(xs[ub - 1] + 1, y), id2 = get_id(x, y);
- add_edge(id2, id1);
- ret.push_back({xs[ub - 1] + 1, y});
- }
- }
- return ret;
- }
- int bfs()
- {
- int s = get_id(sx, sy);
- int t = get_id(gx, gy);
- vector<int> dist(400003, INT_MAX / 2);
- dist[s] = 0;
- queue<pii> q;
- q.push({sx, sy});
- while (q.empty() == false) {
- auto h = q.front();
- q.pop();
- int x = h.first, y = h.second;
- int u = get_id(x, y);
- auto reach = direct_add(x, y);
- for (const auto &p : reach) {
- int v = get_id(p.first, p.second);
- if (dist[v] > dist[u] + 1) {
- dist[v] = dist[u] + 1;
- q.push(p);
- }
- }
- }
- return dist[t] == INT_MAX / 2 ? -1 : dist[t];
- }
- int main(int argc, char **argv)
- {
- int x, y;
- cin >> h >> w >> n;
- cin >> sx >> sy;
- cin >> gx >> gy;
- memset(head, -1, sizeof(head));
- for (int i = 0; i < n; ++i)
- cin >> x >> y, hm[x].push_back(y), vm[y].push_back(x);
- for (auto &p : hm)
- sort(p.second.begin(), p.second.end());
- for (auto &p : vm)
- sort(p.second.begin(), p.second.end());
- cout << bfs() << endl;
- return 0;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement