Submission #1158477

#TimeUsernameProblemLanguageResultExecution timeMemory
1158477farrellwCyberland (APIO23_cyberland)C++20
20 / 100
946 ms2162688 KiB
#include "cyberland.h" #include <vector> #include <queue> #include <limits> #include <iostream> using namespace std; typedef long double ld; const ld INF = 1e18; struct State { ld dist; // total time so far int used; // how many times we've used "divide by 2" int node; // For priority_queue in ascending order of dist bool operator>(const State &other) const { return dist > other.dist; } }; double solve(int N, int M, int K, int H, std::vector<int> x, std::vector<int> y, std::vector<int> c, std::vector<int> arr) { // Build adjacency list: adj[u] = list of (v, cost) vector<vector<pair<int, int>>> adj(N); for (int i = 0; i < M; i++) { adj[x[i]].push_back({y[i], c[i]}); adj[y[i]].push_back({x[i], c[i]}); } // Optional: check if H is reachable from 0 by a simple BFS/DFS // so we can return -1 quickly if not. // ------------------------------------------------------------- { vector<bool> visited(N, false); queue<int>q; q.push(0); visited[0] = true; while(!q.empty()) { int cur = q.front(); q.pop(); for (auto &nx : adj[cur]) { int nxt = nx.first; if(!visited[nxt]) { visited[nxt] = true; q.push(nxt); } } } if(!visited[H]) { return -1.0; } } // ------------------------------------------------------------- // dist[node][used] = best time to reach `node` using "divide-by-2" `used` times vector<vector<ld>> dist(N, vector<ld>(K+1, INF)); dist[0][0] = 0.0; // Min-heap for Dijkstra-like expansions priority_queue<State, vector<State>, greater<State>> pq; pq.push(State{0.0, 0, 0}); // (distance=0, used=0, node=0) while(!pq.empty()) { auto [cdist, used, node] = pq.top(); pq.pop(); // If this is not our best known distance, skip if (cdist > dist[node][used]) continue; // If we've reached Cyberland H, we're done! if (node == H) { return (double)cdist; } // Relax edges from current node for (auto &edge : adj[node]) { int nxt = edge.first; ld roadCost = (ld)edge.second; // The base cost to arrive at `nxt` before applying `nxt`'s ability ld baseNewDist = cdist + roadCost; // 1) We can arrive without using any new "divide-by-2" ability: // - If nxt has arr[nxt] == 0, we can zero out the total. // - If nxt has arr[nxt] == 2, we can choose not to halve it, // so the time remains baseNewDist. // - If nxt has arr[nxt] == 1, also remains baseNewDist. ld candidateDist = baseNewDist; if (arr[nxt] == 0) { candidateDist = 0.0; } // No halving used here, so used stays the same if (candidateDist < dist[nxt][used]) { dist[nxt][used] = candidateDist; pq.push(State{candidateDist, used, nxt}); } // 2) If nxt == 2, we also have the *option* to halve after arriving, // provided we still have an available "divide-by-2" use left. if (arr[nxt] == 2 && used < K) { ld halvedDist = baseNewDist / 2.0; if (halvedDist < dist[nxt][used + 1]) { dist[nxt][used + 1] = halvedDist; pq.push(State{halvedDist, used + 1, nxt}); } } } } // If we exhaust the queue without reaching H, it's impossible. return -1.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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...