Submission #1153578

#TimeUsernameProblemLanguageResultExecution timeMemory
1153578elipsenCyberland (APIO23_cyberland)C++20
Compilation error
0 ms0 KiB
#include "cyberland.h" #include <vector> #include <set> #include <unordered_set> #include <unordered_map> #include <queue> #include <utility> #define v vector #define s set #define u_s unordered_set #define u_m unordered_map #define q queue #define p_q priority_queue #define p pair #define ll long long using namespace std; class WorldMap { const ll maxShift = 100000; const double tempInf = 1000000000000000; ll countryCount; ll cyberland; double minimum; u_m<ll, v<p<ll, ll>>> friends; v<double> dspaSourceResult; u_m<ll, double> halvers; u_m<ll, s<p<double, ll>>> customHalvers; u_s<ll> checkedHalvers; v<ll> powers; double runthroughCount = 0; public: // Initialize the world map WorldMap(ll countries, ll destinationIndex) { countryCount = countries; cyberland = destinationIndex; minimum = tempInf; friends.clear(); dspaSourceResult.clear(); halvers.clear(); customHalvers.clear(); checkedHalvers.clear(); powers.clear(); } void connect(ll friend1, ll friend2, ll distance) { friends[friend1].push_back(make_pair(friend2, distance)); friends[friend2].push_back(make_pair(friend1, distance)); } void notePowers(v<ll> arr) { powers = arr; } void dspaSource() { // Initialize stuff dspaSourceResult.clear(); dspaSourceResult.resize(countryCount, tempInf); p_q<p<double, ll>, v<p<double, ll>>, greater<p<double, ll>>> dspaQueue; dspaQueue.push(make_pair(0, 0)); dspaSourceResult[0] = 0; ll selected; ll friendID; ll friendDist; // Go through the queue while (!(dspaQueue.empty())) { selected = dspaQueue.top().second; dspaQueue.pop(); // Go through the first-in-line's friends for (p<ll, ll> fren : friends[selected]) { friendID = fren.first; friendDist = fren.second; // If the friend has 0-powers if (powers[friendID] == 0) { // Propagate only if it hasn't been hit before if (dspaSourceResult[friendID] > 0) { dspaSourceResult[friendID] = 0; // Note that we cannot leave Cyberland if (friendID != cyberland) dspaQueue.push(make_pair(0, friendID)); } } else { // Propagate only if the value changes if (dspaSourceResult[selected] + friendDist < dspaSourceResult[friendID]) { dspaSourceResult[friendID] = dspaSourceResult[selected] + friendDist; // Note that we cannot leave Cyberland if (friendID != cyberland) dspaQueue.push(make_pair(dspaSourceResult[friendID], friendID)); } } } } } void dspaDestination() { // Initialize stuff v<double> dspaDestinationResult(countryCount, tempInf); p_q<p<double, ll>, v<p<double, ll>>, greater<p<double, ll>>> dspaQueue; u_s<ll> halverSet; dspaQueue.push(make_pair(0, cyberland)); dspaDestinationResult[cyberland] = 0; ll selected; ll friendID; ll friendDist; // Go through the queue while (!(dspaQueue.empty())) { selected = dspaQueue.top().second; dspaQueue.pop(); // Go through the first-in-line's friends for (p<ll, ll> fren : friends[selected]) { friendID = fren.first; friendDist = fren.second; // Propagate only if the value changes if (dspaDestinationResult[selected] + friendDist < dspaDestinationResult[friendID]) { dspaDestinationResult[friendID] = dspaDestinationResult[selected] + friendDist; // Log if friend's power is 2 dspaQueue.push(make_pair(dspaDestinationResult[friendID], friendID)); if (powers[friendID] == 2) halverSet.insert(friendID); } } } // Deal with the queue for 2-powers for (auto selected: halverSet) halvers[selected] = dspaDestinationResult[selected]; } void dspaCustom(ll halverInd) { // Initialize stuff v<double> dspaCustomResult(countryCount, tempInf); p_q<p<double, ll>, v<p<double, ll>>, greater<p<double, ll>>> dspaQueue; dspaQueue.push(make_pair(0, halverInd)); dspaCustomResult[halverInd] = 0; ll selected; ll friendID; ll friendDist; // Go through the queue while (!(dspaQueue.empty())) { selected = dspaQueue.top().second; dspaQueue.pop(); // Go through the first-in-line's friends for (p<ll, ll> fren : friends[selected]) { friendID = fren.first; friendDist = fren.second; // Propagate only if the value changes if (dspaCustomResult[selected] + friendDist < dspaCustomResult[friendID]) { dspaCustomResult[friendID] = dspaCustomResult[selected] + friendDist; // Note that we cannot leave Cyberland if (friendID != cyberland) dspaQueue.push(make_pair(dspaCustomResult[friendID], friendID)); // return if friend's power is 2 - this shall be the closest friend if (powers[friendID] == 2) customHalvers[halverInd].insert(make_pair(dspaCustomResult[friendID], friendID)); } } } } double div2(double ans, ll expo) { double k = 2; while (expo != 0) { if (expo & 1) ans = ans / k; expo = expo >> 1; k = k * k; } return ans; } bool navigate(ll halverInd, double currDistance, double lastDistance, ll halvesUsed, ll maxHalves) { // runthroughCount++; if (dspaSourceResult[halverInd] == tempInf) return true; // Navigating from Cyberland back to home; first update double newDist = currDistance + div2(lastDistance, halvesUsed); minimum = min(minimum, newDist + div2(dspaSourceResult[halverInd], halvesUsed)); // Then try to minimize saved path length if ((halvesUsed < maxHalves) && (newDist < minimum - max(minimum * 1.0E-7, 1.0E-7))) { minimum = min(minimum, newDist + div2(dspaSourceResult[halverInd], halvesUsed + 1)); // If maxHalves has not been reached, go through each friend ll friendID; double friendDist; if (checkedHalvers.find(halverInd) == checkedHalvers.end()) { checkedHalvers.insert(halverInd); dspaCustom(halverInd); double minDist = tempInf; for (auto fren : friends[halverInd]) { if (fren.first != cyberland) minDist = min(minDist, ((double) fren.second) * 2); } if (minDist != tempInf) customHalvers[halverInd].insert(make_pair(minDist, halverInd)); } for (auto fren : customHalvers[halverInd]) { friendDist = fren.first; friendID = fren.second; if (friendDist != tempInf) { bool get = navigate(friendID, newDist, friendDist, halvesUsed + 1, maxHalves); if (get) break; } } return false; } else return true; } double determinePath(ll twoPower) { // Perform DijkstraSPA once from source, apply 0 and 1 rules dspaSource(); // Perform DijkstraSPA once from destination, record 2s dspaDestination(); // Then consolidate hereon if (dspaSourceResult[cyberland] == tempInf) return -1; // If Cyberland is reachable p_q<p<double, ll>, v<p<double, ll>>, greater<p<double, ll>>> dfsFromDestinationQueue; minimum = dspaSourceResult[cyberland]; for (auto info : halvers) dfsFromDestinationQueue.push(make_pair(info.second, info.first)); twoPower = min(twoPower, maxShift); // Go through each 2-power starting from destination, dfs-style p<double, ll> currentHalver; while (!(dfsFromDestinationQueue.empty())) { currentHalver = dfsFromDestinationQueue.top(); dfsFromDestinationQueue.pop(); if (currentHalver.first != tempInf) { bool get = navigate(currentHalver.second, 0, currentHalver.first, 0, twoPower); if (get) break; } } return minimum; } }; double solve(ll N, ll M, ll K, ll H, v<ll> x, v<ll> y, v<ll> c, v<ll> arr) { // Rename every int to something more descriptive ll countryCount = N; ll roadCount = M; ll bitShifter = K; ll cyberLocation = H; WorldMap theRoadToCyberland(countryCount, cyberLocation); for (ll road = 0; road < roadCount; road++) theRoadToCyberland.connect(x[road], y[road], c[road]); theRoadToCyberland.notePowers(arr); return theRoadToCyberland.determinePath(bitShifter); }

Compilation message (stderr)

/usr/bin/ld: /tmp/ccGcoAva.o: in function `main':
grader.cpp:(.text.startup+0x71e): undefined reference to `solve(int, int, int, int, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >)'
collect2: error: ld returned 1 exit status