제출 #1157314

#제출 시각아이디문제언어결과실행 시간메모리
1157314TroySer사이버랜드 (APIO23_cyberland)C++20
97 / 100
169 ms61260 KiB
#include <bits/stdc++.h>

using namespace std;
using ll = long long;

vector<vector<ll> > adjList;
map<pair<ll, ll>, double> weightMat;
vector<bool> isReachable;

struct NodeState {
    double distance;
    ll currentNode;
    ll numSpecialsUsed;
};

ll keepMult2(ll numTimes) {
    return pow(2, numTimes);
}

bool myCompFunc(NodeState ns1, NodeState ns2) {
    if (ns1.distance == ns2.distance) {
        if (ns1.currentNode == ns2.currentNode) {
            return (ns1.numSpecialsUsed > ns2.numSpecialsUsed);
        }
        return ns1.currentNode > ns2.currentNode;
    }
    return ns1.distance > ns2.distance;
}

void dfs(ll node, ll H, const vector<vector<ll>>& adjList, vector<bool>& isReachable) {

    if (node == H) return;

    for (auto v : adjList[node]) {
        if (!isReachable[v]) {
            isReachable[v] = true;
            dfs(v, H, adjList, isReachable);
        }
    }

}

double dijkstras(ll H, ll maxSpecials, vector<int> &A) {

    maxSpecials = min(maxSpecials, 35LL);

    ll N = adjList.size();
    
    // {distance, node, number of times special is used}
    priority_queue<NodeState, vector<NodeState>, function<bool(NodeState, NodeState)> > pq(myCompFunc);
    pq.push({0.0, H, 0});

    vector<vector<double> > distances(N, vector<double>(maxSpecials + 1, 1e18));
    distances[H][0] = 0;

    while (!pq.empty()) {

        // store state of how many Ks were used here
        auto [currentDistance, currentNode, currentSpecials] = pq.top();
        pq.pop();

        if (currentDistance > distances[currentNode][currentSpecials]) {
            continue;
        }

        if ((currentNode == 0 || A[currentNode] == 0) && isReachable[currentNode]) {
            return currentDistance;
        }

        for (ll v: adjList[currentNode]) {

            if (v == H) continue;

            if (!isReachable[v]) {
                continue;
            }

            double newDist = currentDistance + ((weightMat[{currentNode, v}]) / keepMult2(currentSpecials));

            if (newDist < distances[v][currentSpecials]) {
                distances[v][currentSpecials] = newDist;
                pq.push({newDist, v, currentSpecials});
            }

            if (A[currentNode] == 2 && currentNode != H && currentSpecials < maxSpecials) {

                double newDistDiv2 = currentDistance + ((weightMat[{currentNode, v}]) / keepMult2(currentSpecials + 1));
                if (newDistDiv2 < distances[v][currentSpecials + 1]) {
                    distances[v][currentSpecials + 1] = newDistDiv2;
                    pq.push({newDistDiv2, v, currentSpecials + 1});
                }

            }

        }

    }

    // cout << "LOL" << endl;

    // for (auto l: distances) {
    //     for (auto g: l) {
    //         cout << g << ", ";
    //     }
    //     cout << endl;
    // }
    // cout << endl;

    // double minimumPossible = 1e18;
    // for (ll i = 0; i < N; i++) {
    //     if (i == 0 || ((A[i] == 0) && isReachable[i])) {
    //         for (ll j = 0; j <= maxSpecials; j++) {
    //             minimumPossible = min(minimumPossible, distances[i][j]);
    //         }
    //     }
    // }

    return 1e18;

    // return minimumPossible;

}

double solve(int N, int M, int K, int H, vector<int> x, vector<int> y, vector<int> c, vector<int> arr) {

    adjList.clear();
    weightMat.clear();

    adjList.resize(N);

    for (ll i = 0; i < M; i++) {
        adjList[x[i]].push_back(y[i]);
        adjList[y[i]].push_back(x[i]);
        weightMat[{x[i], y[i]}] = (double)c[i];
        weightMat[{y[i], x[i]}] = (double)c[i];
    }

    isReachable.clear();
    isReachable.resize(N, false);

    dfs(0, H, adjList, isReachable);
    isReachable[0] = true;

    if (!isReachable[H]) {
        return -1;
    }

    double response = dijkstras(H, K, arr);

    if (response >= 1e18) {
        return -1;
    }

    return response;

}
#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...