// // Created by piotr on 13.03.2024. // #include <ctime> #include <cassert> #include <cstdio> #include <map> #include <queue> #include <vector> const long long MAX_CENA = 1000000000000000000ll; struct Zelki { int masa; long long cena; bool operator<(const Zelki& inny) const { return cena > inny.cena; } }; std::vector<long long> generate_modulos(const int M, const std::vector<Zelki>& kolorowe) { std::vector<long long> C(M, MAX_CENA); for (const Zelki& z : kolorowe) { int modulo = z.masa % M; C[modulo] = std::min(C[modulo], z.cena); } return C; } std::vector<long long> merge_modulos(const int M, const std::vector<long long>& x, const std::vector<Zelki>& kolorowe) { std::vector<long long> C(M, MAX_CENA); for (int i=0; i<M; ++i) { for (const Zelki& z : kolorowe) { int modulo = (i + z.masa) % M; C[modulo] = std::min(C[modulo], x[i] + z.cena); } } return C; } int main() { int N, K, M; assert(scanf("%d%d%d", &N, &K, &M) == 3); std::vector<Zelki> kolorami[K]; for (int n=0; n<N; ++n) { int kolor, masa; long long cena; assert(scanf("%d%d%lld", &kolor, &masa, &cena) == 3); kolorami[kolor-1].push_back({masa, cena}); } std::vector<long long> modulos = generate_modulos(M, kolorami[0]); for (int k=1; k<K; ++k) { modulos = merge_modulos(M, modulos, kolorami[k]); } std::vector<Zelki> zestawy; zestawy.reserve(M); for (int m=1; m<M; ++m) { if (modulos[m] < MAX_CENA) { zestawy.push_back({m, modulos[m]}); } } std::vector<long long> ceny(M, MAX_CENA); ceny[0] = 0; // OK, teraz czas na algorytm grafowy std::priority_queue<Zelki> pq; pq.push({0, 0}); while (!pq.empty()) { int cena = pq.top().cena; int m0 = pq.top().masa; pq.pop(); if (cena > ceny[m0]) { continue; } for (const Zelki& zestaw : zestawy) { int m = (m0 + zestaw.masa) % M; if (ceny[m0] + zestaw.cena < ceny[m]) { ceny[m] = ceny[m0] + zestaw.cena; pq.push({m, ceny[m]}); } } } for (int m=0; m<M; ++m) { printf("%lld\n", ceny[m] < MAX_CENA ? ceny[m] : -1); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | // // Created by piotr on 13.03.2024. // #include <ctime> #include <cassert> #include <cstdio> #include <map> #include <queue> #include <vector> const long long MAX_CENA = 1000000000000000000ll; struct Zelki { int masa; long long cena; bool operator<(const Zelki& inny) const { return cena > inny.cena; } }; std::vector<long long> generate_modulos(const int M, const std::vector<Zelki>& kolorowe) { std::vector<long long> C(M, MAX_CENA); for (const Zelki& z : kolorowe) { int modulo = z.masa % M; C[modulo] = std::min(C[modulo], z.cena); } return C; } std::vector<long long> merge_modulos(const int M, const std::vector<long long>& x, const std::vector<Zelki>& kolorowe) { std::vector<long long> C(M, MAX_CENA); for (int i=0; i<M; ++i) { for (const Zelki& z : kolorowe) { int modulo = (i + z.masa) % M; C[modulo] = std::min(C[modulo], x[i] + z.cena); } } return C; } int main() { int N, K, M; assert(scanf("%d%d%d", &N, &K, &M) == 3); std::vector<Zelki> kolorami[K]; for (int n=0; n<N; ++n) { int kolor, masa; long long cena; assert(scanf("%d%d%lld", &kolor, &masa, &cena) == 3); kolorami[kolor-1].push_back({masa, cena}); } std::vector<long long> modulos = generate_modulos(M, kolorami[0]); for (int k=1; k<K; ++k) { modulos = merge_modulos(M, modulos, kolorami[k]); } std::vector<Zelki> zestawy; zestawy.reserve(M); for (int m=1; m<M; ++m) { if (modulos[m] < MAX_CENA) { zestawy.push_back({m, modulos[m]}); } } std::vector<long long> ceny(M, MAX_CENA); ceny[0] = 0; // OK, teraz czas na algorytm grafowy std::priority_queue<Zelki> pq; pq.push({0, 0}); while (!pq.empty()) { int cena = pq.top().cena; int m0 = pq.top().masa; pq.pop(); if (cena > ceny[m0]) { continue; } for (const Zelki& zestaw : zestawy) { int m = (m0 + zestaw.masa) % M; if (ceny[m0] + zestaw.cena < ceny[m]) { ceny[m] = ceny[m0] + zestaw.cena; pq.push({m, ceny[m]}); } } } for (int m=0; m<M; ++m) { printf("%lld\n", ceny[m] < MAX_CENA ? ceny[m] : -1); } } |