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