#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 time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |