#include "cyberland.h"
#include <vector>
#include <queue>
#include <tuple>
using namespace std;
typedef long double ld;
const ld INF = 1e18;
struct State {
    ld cost;
    int node;
    int used; // number of divide-by-2 actions used so far
    bool operator>(const State &other) const {
        return cost > other.cost;
    }
};
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 the graph.
    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]});
    }
    
    // We'll keep the best cost to reach each (node, usedDivide) state.
    vector<vector<ld>> dist(N, vector<ld>(K + 1, INF));
    // Priority queue for Dijkstra: (cost, node, usedDivide)
    priority_queue<State, vector<State>, greater<State>> pq;
    
    // Start from country 0 with cost 0 and no divide-by-2 operations used.
    dist[0][0] = 0;
    pq.push({0, 0, 0});
    
    while (!pq.empty()) {
        State cur = pq.top();
        pq.pop();
        ld d = cur.cost;
        int u = cur.node;
        int used = cur.used;
        
        if (d != dist[u][used]) continue;  // outdated state
        // If we reached Cyberland, we have an answer.
        if (u == H)
            return (double)d;
        
        // At the current node, you may choose to use its special ability.
        // Note: You can use the ability at most once per visit.
        // For a clear ability (arr[u] == 0), your total cost resets to 0.
        if (arr[u] == 0) {
            if (d != 0 && 0 < dist[u][used]) {
                dist[u][used] = 0;
                pq.push({0, u, used});
            }
        }
        // For a divide-by-2 ability, you must not have exceeded K uses.
        if (arr[u] == 2 && used < K) {
            ld newCost = d / 2.0;
            if (newCost < dist[u][used + 1]) {
                dist[u][used + 1] = newCost;
                pq.push({newCost, u, used + 1});
            }
        }
        
        // Now relax all outgoing edges (without using any ability at the current node).
        for (auto &edge : adj[u]) {
            int v = edge.first;
            int w = edge.second;
            ld nd = d + w;
            if (nd < dist[v][used]) {
                dist[v][used] = nd;
                pq.push({nd, v, used});
            }
        }
    }
    
    return -1;
}
| # | 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... |