Submission #1158379

#TimeUsernameProblemLanguageResultExecution timeMemory
1158379countlessCyberland (APIO23_cyberland)C++20
0 / 100
17 ms7236 KiB
#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 {
        return dist > other.dist;
    }
};

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[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
    vector<bool> real(N, false);
    checkReal(0, H, adj, real);

    // start djikstra's from H
    vector<ld> dist(N, INF);
    dist[H] = 0;
    priority_queue<T, vector<T>, greater<T>> pq;
    pq.push({0, 0, H});
    bool flag = false;

    ld ans = INF;

    while (!pq.empty()) {
        const auto [cdist, k, node] = pq.top();
        pq.pop();

        if (flag && node == H) continue;
        if (!real[node]) continue;

        if (arr[node] == 0 || node == 0) {
            ans = min(ans, cdist);
            break;
        }

        if (cdist != dist[node]) continue;
        for (const pair<int, int> &i : adj[node]) {
            // power-up 2
            if (arr[i.first] == 2 && cdist + (i.second / (1 << (k + 1))) < dist[i.first] && k < K && i.first != H) {
                dist[i.first] = cdist + (i.second / (1 << (k + 1)));
                pq.push({dist[i.first], k + 1, i.first});
            }

            // power-up 1
            else if (cdist + (i.second / (1 << k)) < dist[i.first] && i.first != H) {
                dist[i.first] = cdist + (i.second / (1 << k));
                pq.push({dist[i.first], k, i.first});
            }
        }

        if (node == H) {
            flag = true;
        }
    }

    if (ans == INF) return -1;

    return ans;
}
#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...