Submission #1359842

#TimeUsernameProblemLanguageResultExecution timeMemory
1359842anangoSky Walking (IOI19_walk)C++20
10 / 100
4118 ms809856 KiB
#include "walk.h"
#include <bits/stdc++.h>
using namespace std;
#define int long long

int HASH = 1LL<<30;
int INF = 1LL<<61;


struct Node {
    int building_num;
    int height;
    int ID;
};
int n,m;

long long min_distance(std::vector<signed> x, std::vector<signed> h, std::vector<signed> l, std::vector<signed> r, std::vector<signed> y, signed s, signed g) {
    n = h.size();
    m = y.size();
    unordered_map<int,vector<pair<int,int>>> adjlist; //other node and weight
    vector<vector<int>> skywalks_for_building(n);
    vector<vector<int>> buildings_for_skywalk(m);
    vector<Node> nodes; //building num, height

    for (int i=0; i<n; i++) {
        for (int j=0; j<m; j++) {
            if (l[j] <= i && i <= r[j] && y[j] <= h[i]) {
                //cout << "WORKING " << i << " " << j << endl;
                nodes.push_back({i, y[j], i*HASH+y[j]});
                skywalks_for_building[i].push_back(j);
                buildings_for_skywalk[j].push_back(i); //SHOULD NATURALLY BE SORTED BECAUSE WE GO IN INCREASING i
            }
        }
        nodes.push_back({i,0,i*HASH});
    }
    for (int i=0; i<n; i++) {
        sort(skywalks_for_building[i].begin(), skywalks_for_building[i].end(), [&](const int i1, const int i2) {
            return y[i1] < y[i2];
        });
    }
    auto add_edge = [&](int i1, int i2, int w) {
        //cout << "ADDING EDGE " << i1/HASH << " " << i1%HASH << " " << i2/HASH << " " << i2%HASH << " " << w << endl;
        adjlist[i1].push_back({i2,w});
        adjlist[i2].push_back({i1,w});
    };
    for (int i=0; i<n; i++) {
        for (int j=1; j<skywalks_for_building[i].size(); j++) {
            int node_1 = i*HASH+y[skywalks_for_building[i][j]];
            int node_2 = i*HASH+y[skywalks_for_building[i][j-1]];
            int dist = y[skywalks_for_building[i][j]] - y[skywalks_for_building[i][j-1]];
            add_edge(node_1, node_2, dist);
        }
        if (skywalks_for_building[i].size()>0) {
            int node_1 = i*HASH+y[skywalks_for_building[i][0]];
            int node_2 = i*HASH+0;
            int dist = y[skywalks_for_building[i][0]];
            add_edge(node_1, node_2, dist);
        }
    }
    //cout << "HORIZONTAL " << endl;
    for (int j=0; j<m; j++) {
        //cout << j << " " << buildings_for_skywalk[j].size() << endl;
        for (int i=1; i<buildings_for_skywalk[j].size(); i++) {
            //cout << "TRYING " << i << " " << j << endl;
            int node_1 = (buildings_for_skywalk[j][i])*HASH + y[j];
            int node_2 = (buildings_for_skywalk[j][i-1])*HASH + y[j];
            int dist = x[buildings_for_skywalk[j][i]] - x[buildings_for_skywalk[j][i-1]];
            add_edge(node_1, node_2, dist);
        }
    }
    int start_ID = s * HASH;
    int end_ID = g * HASH;
    priority_queue<pair<int,int>> distances; //naturally a maxheap so flip the signs
    unordered_map<int,int> dist;
    unordered_map<int,int> proc;
    for (auto i:nodes) {
        dist[i.ID] = INF;
    }
    dist[start_ID] = 0;
    distances.push({-0, start_ID});
    while (distances.size()) {
        pair<int,int> top = distances.top();
        distances.pop();
        int di = -top.first;
        int no = top.second;
        //cout << "DOING " << di << " " << no << " " << adjlist[no].size() << endl;
        if (dist[no] < di || proc[no]) continue;
        proc[no] = 1;
        for (auto edge:adjlist[no]) {
            int nei = edge.first;
            int wei = edge.second;
            if (di+wei < dist[nei]) {
                dist[nei] = di + wei;
                distances.push({-dist[nei], nei});
            }
        }
    }
    int res = dist[end_ID];
    if (res==INF) {
        return -1;
    }

	return res;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...