#include <iostream>
#include <array>
#include <vector>
#include <map>
#include <queue>
#include <limits>
using ll = long long;
const int MAX_N = 100*1000 + 2;
struct AdjEdge {
int toNode;
int color;
int price;
};
std::array<std::vector<AdjEdge>, MAX_N> graph;
int solve(int n, int m) {
std::array<int, MAX_N> dists;
dists.fill(std::numeric_limits<int>::max());
using T = std::pair<int, int>;
std::priority_queue<T, std::vector<T>, std::greater<T>> pq;
pq.push({0, 0});
dists[0] = 0;
while (!pq.empty()) {
auto [dist, node] = pq.top();
pq.pop();
if (dists[node] != dist)
continue;
std::map<int, int> colorPrice, minColorDist;
for (auto adj : graph[node]) {
colorPrice[adj.color] += adj.price;
if (minColorDist.find(adj.color) != minColorDist.end())
minColorDist[adj.color] = std::min(minColorDist[adj.color], dists[adj.toNode]);
else
minColorDist[adj.color] = dists[adj.toNode];
}
for (auto adj : graph[node]) {
int newDist = dist + adj.price;
newDist = std::min(newDist, dist + colorPrice[adj.color] - adj.price);
if (minColorDist.find(adj.color) != minColorDist.end() && minColorDist[adj.color] != std::numeric_limits<int>::max()) {
newDist = std::min(newDist, minColorDist[adj.color] + colorPrice[adj.color] - adj.price);
}
if (newDist < dists[adj.toNode]) {
dists[adj.toNode] = newDist;
pq.push({newDist, adj.toNode});
}
}
}
return dists[n - 1];
}
int main() {
int n, m; std::cin >> n >> m;
for (int i = 0; i < m; ++i) {
int a, b, c, p; std::cin >> a >> b >> c >> p; a--; b--; c--;
graph[a].push_back({b, c, p});
graph[b].push_back({a, c, p});
}
int res = solve(n, m);
if (res == std::numeric_limits<int>::max()) {
std::cout << -1 << std::endl;
} else {
std::cout << res << std::endl;
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |