#pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #include using namespace std; using pii=pair; using tii=tuple; using qii=tuple; using ll=long long; using ull=unsigned long long; using ld=long double; constexpr int INF=1e9; constexpr ll INF_ll=1e18; #define rep(i,n) for (int i=0;i<(int)(n);i++) #define replr(i,l,r) for (int i=(int)(l);i<(int)(r);i++) #define all(v) v.begin(),v.end() #define len(v) ((int)v.size()) template inline bool chmin(T &a,const T &b){ if(a>b){ a=b; return true; } return false; } template inline bool chmax(T &a,const T &b){ if(a(now-start).count(); return ms; } int get_ms_all_program(){ auto now=chrono::steady_clock::now(); int ms=chrono::duration_cast(now-program_start).count(); return ms; } } mt19937 mt; uint32_t rand_int(uint32_t r){ //[0,r) assert(r!=0); return ((uint64_t)mt()*r)>>32; } int rand_int(int l,int r){ //[l,r) assert(l T get_random_element(const vector &v){ assert(!v.empty()); return v[rand_int(len(v))]; } template void add(vector &a,vector b){ for(auto i:b) a.push_back(i); } template SA_State SA(const SA_State &first_state){ SA_State state=first_state,best_state=state; int loop_cnt=0,accept_cnt=0,update_cnt=0; int ms=0; double temp=start_temp; Timer::snap(); while(true){ if(true){ ms=Timer::get_ms(); if(limit_ms<=ms) break; //double t=(double)ms/limit_ms; temp=start_temp-(start_temp-end_temp)/limit_ms*ms; //temp=pow(start_temp,1-t)*pow(end_temp,t); } loop_cnt++; double accept_diff=log(rand_double())*temp; bool accepted=state.modify(accept_diff); if(accepted){ accept_cnt++; if(best_state.score X,Y,W; array,N> W_score; ll W_score_sum=0; struct Plan{ int a,b; int s,t; auto operator<=>(const Plan &other) const{ return this->t<=>other.t; } }; array P; array,N> D; array,N> Is_target; map Time_string; vector Target_times; namespace Solver{ void calc_times(int j,int t,const vector &sorted_plans,array &s){ s.fill(-INF); s[j]=t; for(const auto &plan:sorted_plans){ if(plan.t<=s[plan.b]&&s[plan.a],21*N> memo_s_sq; auto tours_to_ans(array,K> tours){ array,K> ans; rep(k,K){ if(tours.empty()) continue; int x=tours[k].back(),t=21*60; tours[k].pop_back(); while(!tours[k].empty()){ int y=tours[k].back(); if(t-D[y][x]<6*60) break; if(x==y){ tours[k].pop_back(); continue; } ans[k].emplace_back(y,x,t-D[y][x],t); t-=D[y][x]; x=y; tours[k].pop_back(); } reverse(all(ans[k])); } return ans; } ll calc_now_ci(int j,const auto &s_sq,const auto &s_ci){ int sum=0; rep(i,N){ sum+=Is_target[j][i]*W[i]*(s_sq[i],N> square_t_plans; array,N> square_next_update; int calc_score(array,K> tours,int kr=K){ vector plans; rep(k,kr){ if(tours.empty()) continue; int x=tours[k].back(),t=21*60; tours[k].pop_back(); while(!tours[k].empty()){ int y=tours[k].back(); if(t-D[y][x]<6*60) break; if(x==y){ tours[k].pop_back(); continue; } plans.emplace_back(y,x,t-D[y][x],t); t-=D[y][x]; x=y; tours[k].pop_back(); } } sort(all(plans)); reverse(all(plans)); array,N> circle_t_plans; for(auto plan:plans){ circle_t_plans[plan.b].push_back(plan.t); } rep(i,N) sort(all(circle_t_plans[i])); array,N> circle_next_update; rep(j,N){ circle_next_update[j].fill(false); rep(t_idx,len(Target_times)){ auto itr_circle=upper_bound(all(circle_t_plans[j]),Target_times[t_idx]); if(itr_circle!=circle_t_plans[j].end()&&*itr_circle<=Target_times[t_idx+1]){ circle_next_update[j][t_idx]=true; } } } ll ci=0; for(int j=0;j s_ci; calc_times(j,Target_times.front(),plans,s_ci); auto s_sq=memo_s_sq[j*21+(Target_times.front()-11*60)/30]; ll now_ci=calc_now_ci(j,s_sq,s_ci); rep(t_idx,len(Target_times)){ ci+=now_ci; if(t_idx+1 w_sum; int get_random_city(){ return upper_bound(all(w_sum),rand_int(w_sum.back()))-w_sum.begin()-1; } int get_random_city_near(int x){ while(true){ int y=get_random_city(); if(x==y) continue; double prob=1/max(1.0,(double)D[x][y]/60); if(rand_double() &tour){ if(tour.empty()) tour.push_back(get_random_city()); int x=tour.back(),t=21*60; tour.pop_back(); vector new_tour; new_tour.push_back(x); while(true){ int y=-1; if(tour.empty()){ y=get_random_city(); }else{ y=tour.back(); tour.pop_back(); } if(x==y) continue; if(t-D[y][x]<6*60) break; new_tour.push_back(y); t-=D[y][x]; x=y; } reverse(all(new_tour)); tour=new_tour; } struct State{ set vis; array,K> tours; int score=0; int k=0; State(){ rep(k,K){ update_tour(tours[k]); } score=0; } bool modify(double accept_diff){ auto new_tours=tours; int r=rand_int(4); int sz=len(new_tours[k]); if(r==0){ int idx=rand_int(sz+1); int x=-1; if(idx==sz) x=get_random_city_near(new_tours[k][idx-1]); else x=get_random_city_near(new_tours[k][idx]); new_tours[k].insert(new_tours[k].begin()+idx,x); }else if(r==1){ if(new_tours[k].empty()) return false; new_tours[k].erase(new_tours[k].begin()+rand_int(sz)); }else if(r==2){ if(new_tours[k].empty()) return false; int idx=rand_int(sz); int x=-1; if(idx==sz-1) x=get_random_city_near(new_tours[k][idx-1]); else x=get_random_city_near(new_tours[k][idx+1]); new_tours[k][idx]=x; }else if(r==3){ swap(new_tours[k][rand_int(sz)],new_tours[k][rand_int(sz)]); } update_tour(new_tours[k]); int new_score=calc_score(new_tours,k+1); if(accept_diff<=new_score-score){ score=new_score; tours=new_tours; return true; } return false; } }; void solve(){ w_sum.resize(N+1,0); rep(i,N) w_sum[i+1]=w_sum[i]+W[i]; vector plans(all(P)); sort(all(plans)); reverse(all(plans)); rep(j,N){ for(auto t:Target_times){ calc_times(j,t,plans,memo_s_sq[j*21+(t-11*60)/30]); } } rep(i,M){ square_t_plans[P[i].b].push_back(P[i].t); } rep(i,N) sort(all(square_t_plans[i])); rep(j,N){ square_next_update[j].fill(false); rep(t_idx,len(Target_times)){ auto itr_square=upper_bound(all(square_t_plans[j]),Target_times[t_idx]); if(itr_square!=square_t_plans[j].end()&&*itr_square<=Target_times[t_idx+1]){ square_next_update[j][t_idx]=true; } } } array,K> ans; State state; rep(k,K){ state.k=k; state=SA(state); } ans=tours_to_ans(state.tours); rep(k,K){ cout << len(ans[k]) << '\n'; rep(i,len(ans[k])){ if(1<=i){ assert(ans[k][i-1].b==ans[k][i].a); assert(ans[k][i-1].t<=ans[k][i].s); } assert(Time_string.contains(ans[k][i].s)); assert(Time_string.contains(ans[k][i].t)); assert(ans[k][i].t-ans[k][i].s==D[ans[k][i].a][ans[k][i].b]); } for(auto plan:ans[k]){ cout << plan.a+1 << ' ' << Time_string[plan.s] << ' ' << plan.b+1 << ' ' << Time_string[plan.t] << '\n'; } } cerr << state.score << ' ' << Timer::get_ms_all_program() << ' ' << endl; } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); Timer::program_start_snap(); int n,r; cin >> n >> r; assert(n==N); assert(r==R); rep(i,N) cin >> X[i] >> Y[i] >> W[i]; int m; cin >> m; assert(m==M); rep(i,M){ int a,b; string s,t; cin >> a >> s >> b >> t; a--; b--; P[i].a=a; P[i].b=b; int sx=stoi(s.substr(0,2)),sy=stoi(s.substr(3,2)); int tx=stoi(t.substr(0,2)),ty=stoi(t.substr(3,2)); P[i].s=sx*60+sy; P[i].t=tx*60+ty; } int k; cin >> k; assert(k==K); rep(i,N){ rep(j,N){ double d=hypot(X[i]-X[j],Y[i]-Y[j]); int t=ceil(60*d/800+40); while(t%5!=0) t++; D[i][j]=t; } } for(int i=6;i<=21;i++){ for(int j=0;j<60;j+=5){ string sx=to_string(i),sy=to_string(j); while(len(sx)<2) sx.insert(sx.begin(),'0'); while(len(sy)<2) sy.insert(sy.begin(),'0'); Time_string[i*60+j]=sx+":"+sy; if(i==21) break; } } for(int i=11;i<=21;i++){ for(int j=0;j<60;j+=30){ Target_times.push_back(i*60+j); if(i==21) break; } } rep(i,N){ rep(j,N){ ll x=((ll)(X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]))*16; if(R*R<=x){ Is_target[i][j]=true; }else{ Is_target[i][j]=false; } } } rep(i,N){ rep(j,N){ W_score[i][j]=(ll)W[i]*W[j]; } } W_score_sum=0; rep(i,N){ rep(j,N){ if(!Is_target[i][j]) continue; rep(_,len(Target_times)){ W_score_sum+=W_score[i][j]; } } } Solver::solve(); exit(0); }