#include "cyberland.h"
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
typedef long long ll;
typedef long double ld;
const ld INF = 1e18;
struct T {
    ld dist;
    int k;
    int node;
    bool operator>(const T &other) const {
        if (dist != other.dist) return dist > other.dist;
        if (k != other.k) return k > other.k;
        return node > other.node;
    }
};
// Now performing floating point division properly.
ld divByPow2(int x, int k) {
    if (k > 30) return 0;
    return (ld)x / (1LL << k);
}
void checkReal(int start, int H, vector<vector<pair<int, int>>> &adj, vector<bool> &real) {
    real[start] = true;
    for (const pair<int, int> &i : adj[start]) {
        if (i.first == H) real[H] = true;
        if (i.first != H && !real[i.first]) {
            checkReal(i.first, H, adj, real);
        }
    }
}
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) {
    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]});
    }
    // find "real" nodes (reachable from country 0)
    vector<bool> real(N, false);
    checkReal(0, H, adj, real);
    if (!real[H]) return -1;
    real[H] = false;
    // run Dijkstra's starting from Cyberland (country H)
    vector<vector<ld>> dist(N, vector<ld>(K + 1, INF));
    dist[H][0] = 0;
    priority_queue<T, vector<T>, greater<T>> pq;
    pq.push({0, 0, H});
    while (!pq.empty()) {
        auto [cdist, k, node] = pq.top();
        pq.pop();
        // if we reached our home country (or a country with ability 0) that is reachable, we're done.
        if ((node == 0 || arr[node] == 0) && real[node]) {
            return cdist;
        }
        if (cdist != dist[node][k]) continue;
        for (const pair<int, int> &edge : adj[node]) {
            int next = edge.first;
            int cost = edge.second;
            if (!real[next]) continue;
            // normal travel without using divide-by-2 ability
            ld newDist = cdist + divByPow2(cost, k);
            if (newDist < dist[next][k]) {
                dist[next][k] = newDist;
                pq.push({newDist, k, next});
            }
            // if the next country has the divide-by-2 ability, and we haven't used it too many times yet
            if (k < K && arr[next] == 2) {
                ld newDist2 = cdist + divByPow2(cost, k + 1);
                if (newDist2 < dist[next][k + 1]) {
                    dist[next][k + 1] = newDist2;
                    pq.push({newDist2, k + 1, next});
                }
            }
        }
    }
    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... |