#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define ll long long class Random { static uint32_t xorshift() { static uint32_t x = 123456789, y = 362436039, z = 521288629, w = 88675123; uint32_t t = x ^ (x << 11); x = y; y = z; z = w; return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); } public: inline static uint32_t randrange(unsigned x) { return xorshift() % x; } // [0, x) inline static uint32_t randrange(unsigned x, unsigned y) { return randrange(y - x) + x; } // [x, y) inline static float random() { return (xorshift() + 0.5) * (1.0 / UINT_MAX); } // [0.0, 1.0) }; class Timer { chrono::time_point start; public: Timer() : start(chrono::steady_clock::now()) {} unsigned short get_ms() { // 経過時間を返す auto now_time = chrono::steady_clock::now(); return chrono::duration_cast(now_time - start).count(); } }; Timer timer; struct City { int x, y, w; }; struct Flight { int a, s, b, t; }; constexpr int MAX_N = 47; constexpr int MAX_M = 400; constexpr int MAX_K = 25; constexpr int TARGET_CNT = 21; constexpr int NEG_INF = -1000000000; constexpr int DAY_START = 6 * 60; constexpr int DAY_END = 21 * 60; constexpr int MAX_C = 64; int N, R, M, K; City cities[MAX_N + 1]; Flight square_flights[MAX_M]; int target_times[TARGET_CNT]; int s_sq_latest[MAX_N + 1][MAX_N + 1][TARGET_CNT]; int travel_time_min[MAX_N + 1][MAX_N + 1]; bool valid_pair[MAX_N + 1][MAX_N + 1]; long long pair_score[MAX_N + 1][MAX_N + 1]; bool won[MAX_N + 1][MAX_N + 1][TARGET_CNT]; int plane_now_city[MAX_K]; int plane_now_time[MAX_K]; int plane_cnt[MAX_K]; int out_a[MAX_K][MAX_C]; int out_s[MAX_K][MAX_C]; int out_b[MAX_K][MAX_C]; int out_t[MAX_K][MAX_C]; int parse_time(const string& s) { int h = (s[0] - '0') * 10 + (s[1] - '0'); int m = (s[3] - '0') * 10 + (s[4] - '0'); return h * 60 + m; } string format_time(int t) { int h = t / 60; int m = t % 60; if (m < 0) { m += 60; h--; } h = max(0, min(99, h)); m = max(0, min(59, m)); char buf[6]; snprintf(buf, sizeof(buf), "%02d:%02d", h, m); return string(buf); } void build_target_times() { for (int idx = 0; idx < TARGET_CNT; idx++) { target_times[idx] = 11 * 60 + idx * 30; } } void precompute_square_latest_departure() { build_target_times(); int latest_from[MAX_N + 1]; for (int dst = 1; dst <= N; dst++) { for (int tid = 0; tid < TARGET_CNT; tid++) { for (int city = 1; city <= N; city++) latest_from[city] = NEG_INF; latest_from[dst] = target_times[tid]; bool updated = true; while (updated) { updated = false; for (int f = 0; f < M; f++) { const Flight& fl = square_flights[f]; if (fl.t <= latest_from[fl.b] && latest_from[fl.a] < fl.s) { latest_from[fl.a] = fl.s; updated = true; } } } for (int src = 1; src <= N; src++) { s_sq_latest[src][dst][tid] = latest_from[src]; } } } } void precompute_city_info() { for (int i = 1; i <= N; i++) { for (int j = 1; j <= N; j++) { if (i == j) { travel_time_min[i][j] = 0; valid_pair[i][j] = false; pair_score[i][j] = 0; continue; } const double dx = static_cast(cities[i].x - cities[j].x); const double dy = static_cast(cities[i].y - cities[j].y); const double d = sqrt(dx * dx + dy * dy); const double raw = 60.0 * d / 800.0 + 40.0; travel_time_min[i][j] = static_cast(ceil(raw / 5.0)) * 5; valid_pair[i][j] = (d >= 0.25 * static_cast(R)); pair_score[i][j] = 1LL * cities[i].w * cities[j].w; } } } long long build_greedy_schedule() { memset(won, 0, sizeof(won)); for (int p = 0; p < K; p++) { plane_now_city[p] = 0; plane_now_time[p] = DAY_START; plane_cnt[p] = 0; } long long total_gain = 0; int ord[MAX_K]; while (true) { int p = -1; int best_time = DAY_END; for (int i = 0; i < K; i++) ord[i] = i; for (int i = K - 1; i > 0; i--) { const int j = Random::randrange(i + 1); swap(ord[i], ord[j]); } for (int ii = 0; ii < K; ii++) { const int i = ord[ii]; if (plane_now_time[i] < best_time) { best_time = plane_now_time[i]; p = i; } } if (p == -1 || best_time >= DAY_END) break; const int now = plane_now_time[p]; double best_eval = -1.0; long long best_gain = -1; int best_u = -1, best_v = -1, best_s = -1, best_arr = -1; const int u_l = (plane_now_city[p] == 0 ? 1 : plane_now_city[p]); const int u_r = (plane_now_city[p] == 0 ? N : plane_now_city[p]); for (int u = u_l; u <= u_r; u++) { for (int v = 1; v <= N; v++) { if (u == v) continue; const int dur = travel_time_min[u][v]; for (int s = now; s + dur <= DAY_END; s += 5) { const int arr = s + dur; long long gain = 0; if (valid_pair[u][v]) { for (int tid = 0; tid < TARGET_CNT; tid++) { if (arr <= target_times[tid] && s_sq_latest[u][v][tid] < s && !won[u][v][tid]) { gain += pair_score[u][v]; } } } const int consumed = s - now + dur; const double eval = static_cast(gain) / static_cast(consumed); if (eval > best_eval || (eval == best_eval && gain > best_gain)) { best_eval = eval; best_gain = gain; best_u = u; best_v = v; best_s = s; best_arr = arr; } } } } if (best_u == -1 || plane_cnt[p] >= MAX_C) { plane_now_time[p] = DAY_END; continue; } if (best_gain <= 0) { int rep_u = -1, rep_v = -1, rep_arr = -1; int cand = 0; for (int u = u_l; u <= u_r; u++) { for (int v = 1; v <= N; v++) { if (u == v) continue; const int arr = now + travel_time_min[u][v]; if (arr > DAY_END) continue; cand++; if (Random::randrange(cand) == 0) { rep_u = u; rep_v = v; rep_arr = arr; } } } if (rep_u == -1) { plane_now_time[p] = DAY_END; continue; } best_u = rep_u; best_v = rep_v; best_s = now; best_arr = rep_arr; } else { total_gain += best_gain; } if (valid_pair[best_u][best_v]) { for (int tid = 0; tid < TARGET_CNT; tid++) { if (best_arr <= target_times[tid] && s_sq_latest[best_u][best_v][tid] < best_s) { won[best_u][best_v][tid] = true; } } } const int idx = plane_cnt[p]++; out_a[p][idx] = best_u; out_s[p][idx] = best_s; out_b[p][idx] = best_v; out_t[p][idx] = best_arr; plane_now_city[p] = best_v; plane_now_time[p] = best_arr; } return total_gain; } int main(){ ios::sync_with_stdio(false); cin.tie(0); timer = Timer(); // タイマー初期化 cin >> N >> R; cerr << N << " " << R << "\n"; for (int i = 1; i <= N; i++) { cin >> cities[i].x >> cities[i].y >> cities[i].w; } cin >> M; cerr << M << "\n"; for (int i = 0; i < M; i++) { string s, t; cin >> square_flights[i].a >> s >> square_flights[i].b >> t; square_flights[i].s = parse_time(s); square_flights[i].t = parse_time(t); } cin >> K; precompute_city_info(); precompute_square_latest_departure(); long long best_total_gain = -1; int best_plane_cnt[MAX_K]; int best_out_a[MAX_K][MAX_C]; int best_out_s[MAX_K][MAX_C]; int best_out_b[MAX_K][MAX_C]; int best_out_t[MAX_K][MAX_C]; do { const long long cur_gain = build_greedy_schedule(); if (cur_gain > best_total_gain) { best_total_gain = cur_gain; memcpy(best_plane_cnt, plane_cnt, sizeof(plane_cnt)); memcpy(best_out_a, out_a, sizeof(out_a)); memcpy(best_out_s, out_s, sizeof(out_s)); memcpy(best_out_b, out_b, sizeof(out_b)); memcpy(best_out_t, out_t, sizeof(out_t)); } } while (timer.get_ms() < 980); for (int p = 0; p < K; p++) { cout << best_plane_cnt[p] << '\n'; for (int i = 0; i < best_plane_cnt[p]; i++) { cout << best_out_a[p][i] << ' ' << format_time(best_out_s[p][i]) << ' ' << best_out_b[p][i] << ' ' << format_time(best_out_t[p][i]) << '\n'; } } }