#include <iostream>
#include <vector>
#include <climits>
using namespace std;
struct Node {
int m;
long c;
Node(int m = 0, long c = 0) : m(m), c(c) {
}
};
template < typename T >
int mod(T v, T m) {
return (v < m) ? v : ((v -= m) < m) ? v
: (v % m);
}
struct Solution {
vector< long > v;
Solution(int m, vector< Node > const &vn) : v(m, LONG_MAX) {
vector< int > ready;
ready.reserve(m);
for (vector< Node >::const_iterator it = vn.begin(); it != vn.end(); ++it) {
Node const &base = *it;
if (v[base.m] == LONG_MAX)
ready.push_back(base.m);
v[base.m] = min(v[base.m], base.c);
vector< int > extras;
int ready_size = ready.size();
for (int i = 0; i < ready_size + (int)extras.size(); ++i) {
int a = i < ready_size ? ready[i] : extras[i - ready_size];
int j = mod(a + base.m, m);
long r = min(v[j], v[a] + v[base.m]);
if (v[j] == LONG_MAX)
ready.push_back(j);
if (v[j] > r)
extras.push_back(j);
v[j] = r;
}
}
v[0] = 0;
}
long operator[](int i) const {
return v[i] == LONG_MAX ? -1 : v[i];
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, k, m, a, b, c;
cin >> n >> k >> m;
vector< vector< Node > > colors(k);
while (n-- && cin >> a >> b >> c)
colors[--a].push_back(Node(mod(b, m), c));
vector< Node > data[2];
int id = 0;
data[id].push_back(Node(0, 0));
vector< int > pos(m);
vector< int > check(m, 0);
int marker = 0;
while (k--) {
vector< Node > &col = colors[k];
vector< Node > &src = data[id], &dst = data[id ^= 1];
++marker;
for (vector< Node >::const_iterator it = src.begin(); it != src.end(); ++it)
for (vector< Node >::iterator node = col.begin(); node != col.end(); ++node) {
long p = mod((*it).m + (*node).m, m);
if (check[p] != marker) {
check[p] = marker;
pos[p] = dst.size();
dst.push_back(Node(p, (*it).c + (*node).c));
} else
dst[pos[p]].c = min(dst[pos[p]].c, (*it).c + (*node).c);
}
src.clear();
}
Solution s(m, data[id]);
for (int i = 0; i < m; ++i)
cout << s[i] << '\n';
}
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 | #include <iostream> #include <vector> #include <climits> using namespace std; struct Node { int m; long c; Node(int m = 0, long c = 0) : m(m), c(c) { } }; template < typename T > int mod(T v, T m) { return (v < m) ? v : ((v -= m) < m) ? v : (v % m); } struct Solution { vector< long > v; Solution(int m, vector< Node > const &vn) : v(m, LONG_MAX) { vector< int > ready; ready.reserve(m); for (vector< Node >::const_iterator it = vn.begin(); it != vn.end(); ++it) { Node const &base = *it; if (v[base.m] == LONG_MAX) ready.push_back(base.m); v[base.m] = min(v[base.m], base.c); vector< int > extras; int ready_size = ready.size(); for (int i = 0; i < ready_size + (int)extras.size(); ++i) { int a = i < ready_size ? ready[i] : extras[i - ready_size]; int j = mod(a + base.m, m); long r = min(v[j], v[a] + v[base.m]); if (v[j] == LONG_MAX) ready.push_back(j); if (v[j] > r) extras.push_back(j); v[j] = r; } } v[0] = 0; } long operator[](int i) const { return v[i] == LONG_MAX ? -1 : v[i]; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, k, m, a, b, c; cin >> n >> k >> m; vector< vector< Node > > colors(k); while (n-- && cin >> a >> b >> c) colors[--a].push_back(Node(mod(b, m), c)); vector< Node > data[2]; int id = 0; data[id].push_back(Node(0, 0)); vector< int > pos(m); vector< int > check(m, 0); int marker = 0; while (k--) { vector< Node > &col = colors[k]; vector< Node > &src = data[id], &dst = data[id ^= 1]; ++marker; for (vector< Node >::const_iterator it = src.begin(); it != src.end(); ++it) for (vector< Node >::iterator node = col.begin(); node != col.end(); ++node) { long p = mod((*it).m + (*node).m, m); if (check[p] != marker) { check[p] = marker; pos[p] = dst.size(); dst.push_back(Node(p, (*it).c + (*node).c)); } else dst[pos[p]].c = min(dst[pos[p]].c, (*it).c + (*node).c); } src.clear(); } Solution s(m, data[id]); for (int i = 0; i < m; ++i) cout << s[i] << '\n'; } |
English