제출 #1319357

#제출 시각아이디문제언어결과실행 시간메모리
1319357Boycl07Robot (JOI21_ho_t4)C++20
34 / 100
3095 ms48204 KiB
#include <bits/stdc++.h> using namespace std; #define all(x) (x).begin(), (x).end() struct Edge { int to, color, cost; }; struct Node { long long d; int u, c; bool operator>(const Node& other) const { return d > other.d; } }; const long long INF = 1e16; // Đủ lớn cho 2e5 * 1e6 vector<Edge> adj[100005]; map<int, long long> sum_c[100005]; map<int, long long> dist[100005]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; for (int i = 0; i < m; ++i) { int u, v, c, p; cin >> u >> v >> c >> p; adj[u].push_back({v, c, p}); adj[v].push_back({u, c, p}); sum_c[u][c] += p; sum_c[v][c] += p; } priority_queue<Node, vector<Node>, greater<Node>> pq; // dist[u][0] là khoảng cách ngắn nhất đến u mà không bị ràng buộc màu // dist[u][c] là khoảng cách ngắn nhất đến u thông qua cạnh màu c (chưa đổi màu c) dist[1][0] = 0; pq.push({0, 1, 0}); while (!pq.empty()) { Node top = pq.top(); pq.pop(); int u = top.u; int c = top.c; long long d = top.d; if (d > dist[u][c]) continue; if (c == 0) { for (auto& e : adj[u]) { // TH1: Đổi màu duy nhất cạnh (u, v) -> tốn p if (dist[e.to].find(0) == dist[e.to].end() || dist[e.to][0] > d + e.cost) { dist[e.to][0] = d + e.cost; pq.push({dist[e.to][0], e.to, 0}); } // TH2: Đổi màu tất cả các cạnh cùng màu c tại u (trừ cạnh này) -> tốn Sum - p long long cost_all = sum_c[u][e.color] - e.cost; if (dist[e.to].find(0) == dist[e.to].end() || dist[e.to][0] > d + cost_all) { dist[e.to][0] = d + cost_all; pq.push({dist[e.to][0], e.to, 0}); } // TH3: Đi vào trạng thái "đang xử lý màu c", không tốn phí ở bước này if (dist[e.to].find(e.color) == dist[e.to].end() || dist[e.to][e.color] > d) { dist[e.to][e.color] = d; pq.push({dist[e.to][e.color], e.to, e.color}); } } } else { // Đang ở trạng thái đặc biệt: đến u bằng màu c (của Strategy B) for (auto& e : adj[u]) { if (e.color == c) { // Chỉ đi tiếp các cạnh cùng màu c để hưởng ưu đãi phí long long cost_rem = sum_c[u][c] - e.cost; if (dist[e.to].find(0) == dist[e.to].end() || dist[e.to][0] > d + cost_rem) { dist[e.to][0] = d + cost_rem; pq.push({dist[e.to][0], e.to, 0}); } } } } } if (dist[n].find(0) == dist[n].end()) cout << -1 << endl; else cout << dist[n][0] << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...