#include #include #include #include struct island { int L; int R; int time; }; #define LEFT 0 #define FROM_LEFT 1 #define ACROSS 2 #define RIGHT 3 #define FROM_RIGHT 4 #define MAX_NUM 10000000 std::vector> get_line_combinations(std::vector &line) { std::vector> comp(line.size(), std::array({0})); if (line.size() == 0) { return comp; } // going across the line std::sort(line.begin(), line.end(), [](const island &a, const island &b) { return a.time < b.time; }); for (size_t i = 0; i < line.size(); i++) { if (i == 0) { comp[i][ACROSS] = line[i].time + line[i].L + line[i].R; } else { comp[i][ACROSS] = comp[i - 1][ACROSS] + line[i].time; } } // going back std::sort(line.begin(), line.end(), [](const island &a, const island &b) { return a.L < b.L; }); std::vector Lused(line.size(), false); int most_right_island = 0; int Lmin = MAX_NUM; int Lval = 0; int dist = 0; int Lindex = 0; int FLmin = 0; std::vector Rused(line.size(), false); int most_left_island = line.size(); int Rmin = MAX_NUM; int Rval = 0; int Rindex = 0; int FRmin = 0; int tmp = 0; for (size_t i = 0; i < line.size(); i++) { if (i == 0) { for (size_t j = 0; j < line.size(); j++) { Lval = line[j].L + line[j].L + line[j].time; if (Lval < Lmin) { Lmin = Lval; Lindex = j; FLmin = line[j].L + line[j].time; } Rval = line[j].R + line[j].R + line[j].time; if (Rval < Rmin) { Rmin = Rval; Rindex = j; FRmin = line[j].R + line[j].time; } } } else { for (size_t j = 0; j < line.size(); j++) { if (!Lused[j]) { if (j < most_right_island) { Lval = comp[i - 1][LEFT] + line[j].time; tmp = comp[i - 1][FROM_LEFT] + line[j].time; } else { dist = line[j].L - line[most_right_island].L; Lval = comp[i - 1][LEFT] + dist + dist + line[j].time; tmp = comp[i - 1][FROM_LEFT] + dist + line[j].time; } if (Lval < Lmin) { Lindex = j; Lmin = Lval; FLmin = tmp; } } if (!Rused[j]) { if (j > most_left_island) { Rval = comp[i - 1][RIGHT] + line[j].time; tmp = comp[i - 1][FROM_RIGHT] + line[j].time; } else { dist = line[j].R - line[most_left_island].R; Rval = comp[i - 1][RIGHT] + dist + dist + line[j].time; tmp = comp[i - 1][FROM_RIGHT] + dist + line[j].time; } if (Rval < Rmin) { Rindex = j; Rmin = Rval; FRmin = tmp; } } } } if (Rindex < most_left_island) { most_left_island = Rindex; } Rused[Rindex] = true; comp[i][RIGHT] = Rmin; Rmin = MAX_NUM; comp[i][FROM_RIGHT] = FRmin; if (Lindex > most_right_island) { most_right_island = Lindex; } Lused[Lindex] = true; comp[i][LEFT] = Lmin; Lmin = MAX_NUM; comp[i][FROM_LEFT] = FLmin; } return comp; } void print_deb(std::vector &RESULT, std::vector> &A) { for (size_t i = 0; i < RESULT.size(); i++) { std::cout << RESULT[i] << " "; } std::cout << std::endl << std::endl; for (size_t i = 0; i < A.size(); i++) { std::cout << A[i][0] << " " << A[i][1] << std::endl; } std::cout << std::endl; } void increse(std::vector> &A) { for (size_t i = 0; i < A.size(); i++) { A[i][0]++; A[i][1]++; } } void print_line(std::vector &line) { for (size_t i = 0; i < line.size(); i++) { std::cout << line[i].L << " " << line[i].time << " " << line[i].R << std::endl; } std::cout << std::endl; } void print_comp(std::vector> &comp) { for (size_t i = 0; i < comp.size(); i++) { std::cout << comp[i][LEFT] << " " << comp[i][FROM_LEFT] << " " << comp[i][ACROSS] << " " << comp[i][RIGHT] << " " << comp[i][FROM_RIGHT] << std::endl; } std::cout << std::endl; } int main(int argc, char *argv[]) { std::ifstream in(argv[1]); if (!in) { std::cout << "Cannot open file.\n"; return 1; } // N = visina int N; // sirina int M; // stevilo otokov int K; in >> N >> M >> K; M--; std::vector> map(N, std::vector()); int x, y, t; for (size_t i = 0; i < K; i++) { in >> x >> y >> t; x--; y--; map[x].emplace_back(island{y, M - y, t}); } in.close(); std::vector RESULT(K + 1, MAX_NUM); std::vector> A(K + 1, {MAX_NUM, MAX_NUM}); RESULT[0] = 0; A[0][0] = 0; A[0][1] = M; std::vector> B = A; int num_of_islands = 0; std::vector> comp = get_line_combinations(map[0]); num_of_islands = comp.size(); for (size_t i = 0; i < comp.size(); i++) { RESULT[i + 1] = std::min(RESULT[i + 1], comp[i][FROM_LEFT]); B[i + 1][0] = std::min(A[i + 1][0], comp[i][LEFT]); B[i + 1][1] = std::min(A[i + 1][1], comp[i][ACROSS]); } increse(B); A = B; int prev = 0; int tmp_left = 0; int tmp_right = 0; int tmp2, tmp3; for (size_t i = 1; i < map.size(); i++) { comp = get_line_combinations(map[i]); num_of_islands += comp.size(); for (size_t j = 1; j <= num_of_islands && comp.size() > 0; j++) { tmp_left = MAX_NUM; tmp_right = MAX_NUM; for (size_t k = 0; k < j && k < comp.size(); k++) { prev = j - (k + 1); RESULT[j] = std::min({RESULT[j], A[prev][0] + comp[k][FROM_LEFT], A[prev][1] + comp[k][FROM_RIGHT]}); tmp2 = std::min({A[j][0], A[prev][0] + comp[k][LEFT], A[prev][1] + comp[k][ACROSS]}); if (tmp2 < tmp_left) { tmp_left = tmp2; } tmp3 = std::min({A[j][1], A[prev][0] + comp[k][ACROSS], A[prev][1] + comp[k][RIGHT]}); if (tmp3 < tmp_right) { tmp_right = tmp3; } } B[j][0] = tmp_left; B[j][1] = tmp_right; } increse(B); A = B; } for (size_t i = 1; i < RESULT.size(); i++) { std::cout << RESULT[i] << " "; } std::cout << std::endl; return 0; }