#include #define REP(i, n) for(int i = 0; i < n; i++) #define BCK(i, n) for(int i = n-1; i >= 0; i--) #define FWD(i, a, b) for(int i = a; i < b; i++) #define ALL(c) (c).begin(), (c).end() #define SIZE(c) ((int)(c).size()) #define pb push_back #define st first #define nd second #define vi vector #define pi pair #define pll pair #define vpi vector #define vpll vector #define mp(a, b) make_pair(a,b) using namespace std; typedef long long LL; typedef double ld; int r,c; struct Ride { int a,b,x,y,s,f; int idx; }; istream& operator>>(istream& is, Ride& r) { return is>>r.a>>r.b>>r.x>>r.y>>r.s>>r.f; } struct Car { int x = 0; int y = 0; int stoptime = 0; vector rides; int arriveTime(const Ride& r) const{ return max(stoptime + abs(x - r.a) + abs(y - r.b), r.s); } int finishTime(const Ride& r) const{ int arr = arriveTime(r); return arr + abs(r.a-r.x) + abs(r.b-r.y); } void serveRide(const Ride& r){ x = r.x; y = r.y; stoptime = finishTime(r); rides.pb(r.idx); } }; int dist(int a, int b, int x, int y){ return abs(a-x) + abs(b-y); } int score(const vector& cars, const vector& rides, int b){ int ret=0; for(auto const& car : cars){ int x=0, y=0, t=0; for(auto i : car.rides){ const Ride& r = rides[i]; t += dist(x,y,r.a,r.b); t = max(t, r.s); if(t == r.s) ret += b; ret += dist(r.a, r.b, r.x, r.y); t += dist(r.a, r.b, r.x, r.y); x = r.x; y = r.y; } } return ret; } vector firstSolution(vector cars, vector rides){ sort(ALL(rides), [](const Ride& a, const Ride& b) {return a.s < b.s;}); if(cars.empty()) return cars; for(const auto& ride : rides){ auto& best = *min_element(ALL(cars), [&ride](const Car& a, const Car& b) {return a.arriveTime(ride) < b.arriveTime(ride);}); if(best.finishTime(ride) >= ride.f) { //cerr << "Ride " << ride.idx << " not served\n"; continue; } //if(best.arriveTime(ride) == ride.s) // cerr << "Got bonus from ride " << ride.idx << '\n'; best.serveRide(ride); } return cars; } vector secondSolution(vector cars, vector rides, float perc){ int size = cars.size() * perc; if(cars.empty()) return cars; //cerr << "size: " << size << " of " << cars.size() << '\n'; REP(i, size){ Car& car = cars[i]; while(1){ Ride* best = nullptr; for(auto& ride : rides){ if(ride.s >= dist(ride.a, ride.b, car.x, car.y) + car.stoptime){ if(!best || best->s >= ride.s){ best = &ride; } } } if(!best) break; car.serveRide(*best); *best = rides.back(); rides.pop_back(); } } FWD(i, size, SIZE(cars)){ Car& car = cars[i]; while(1){ Ride* best = nullptr; for(auto& ride : rides){ if(ride.f > dist(ride.a, ride.b, car.x, car.y) + car.stoptime + dist(ride.a, ride.b, ride.x, ride.y)){ if(!best || dist(best->a, best->b, car.x, car.y) >= dist(ride.a, ride.b, car.x, car.y)){ best = &ride; } } } if(!best) break; car.serveRide(*best); *best = rides.back(); rides.pop_back(); } } return cars; } vector thirdSolution(vector cars, vector rides, float perc){ int size = cars.size() * perc; if(cars.empty()) return cars; //cerr << "size: " << size << " of " << cars.size() << '\n'; random_device rd; mt19937 g(rd()); while(1){ bool chosen = 0; shuffle(cars.begin(), cars.begin() + size, g); REP(i, size){ Car& car = cars[i]; Ride* best = nullptr; for(auto& ride : rides){ if(ride.s >= dist(ride.a, ride.b, car.x, car.y) + car.stoptime){ if(!best || best->s >= ride.s){ best = &ride; } } } if(best){ chosen = 1; car.serveRide(*best); *best = rides.back(); rides.pop_back(); } } if(!chosen) break; } while(1){ bool chosen = 0; shuffle(cars.begin()+size, cars.end(), g); FWD(i, size, SIZE(cars)){ Car& car = cars[i]; Ride* best = nullptr; for(auto& ride : rides){ if(ride.f > dist(ride.a, ride.b, car.x, car.y) + car.stoptime + dist(ride.a, ride.b, ride.x, ride.y)){ if(!best || dist(best->a, best->b, car.x, car.y) >= dist(ride.a, ride.b, car.x, car.y)){ best = &ride; } } } if(best){ chosen = 1; car.serveRide(*best); *best = rides.back(); rides.pop_back(); } } if(!chosen) break; } return cars; } template vector fourthSolution(vector cars, vector rides, func f, Args&&... args){ vector partX(div+1), partY(div+1); partX[0] = partY[0] = 0; FWD(i,1,div+1){ partX[i] = ((LL)r)*i/div; partY[i] = ((LL)c)*i/div; } vector rides_parts[div][div]; vector cars_parts[div][div]; for(const auto& ride : rides){ rides_parts[ride.a*div/r][ride.b*div/c].pb(ride); } int start=0; REP(i,div) REP(j,div){ int part = rides_parts[i][j].size() * cars.size() / rides.size(); cars_parts[i][j].resize(part); start += part; } cars.resize(cars.size() - start); vector result; REP(i,div) REP(j,div){ #define algo firstSolution for(auto const& c : f(cars_parts[i][j], rides_parts[i][j], forward(args)...)) result.pb(c); } vector XD(rides.size()); for(auto const& c : result) for(auto i : c.rides) XD[i] = true; vector notdone; REP(i,SIZE(XD)) if(!XD[i]) notdone.pb(rides[i]); for(auto const& c : f(cars, notdone, forward(args)...)) result.pb(c); #undef algo return result; } int main(){ srand(time(NULL)); ios_base::sync_with_stdio(false); int f,n,b,t; cin>>r>>c>>f>>n>>b>>t; vector rides(n); vector cars(f); REP(i,n){ cin>>rides[i]; rides[i].idx = i; } vector best; //const auto& sol1 = firstSolution(cars, rides); best = firstSolution(cars, rides); int bestscore = score(best, rides, b); REP(i, 21){ float perc = 0.05f * i; { const auto& temp = secondSolution(cars, rides, perc); int tempscore = score(temp, rides, b); if(tempscore > bestscore){ bestscore = tempscore; best = temp; } } { const auto& temp = fourthSolution<2>(cars, rides, secondSolution, perc); int tempscore = score(temp, rides, b); if(tempscore > bestscore){ bestscore = tempscore; best = temp; } } { const auto& temp = fourthSolution<3>(cars, rides, secondSolution, perc); int tempscore = score(temp, rides, b); if(tempscore > bestscore){ bestscore = tempscore; best = temp; } } } REP(i, 21){ float perc = 0.05f * i; { const auto& temp = thirdSolution(cars, rides, perc); cerr << "third solution " << i <<" " << score(temp, rides, b)< bestscore){ bestscore = tempscore; best = temp; } } { const auto& temp = fourthSolution<2>(cars, rides, thirdSolution, perc); cerr << "fourth solution " << i <<" " << score(temp, rides, b)< bestscore){ bestscore = tempscore; best = temp; } } { const auto& temp = fourthSolution<3>(cars, rides, thirdSolution, perc); cerr << "fourth solution " << i <<" " << score(temp, rides, b)< bestscore){ bestscore = tempscore; best = temp; } } } { const auto& temp = fourthSolution<2>(cars, rides, firstSolution); cerr << "fourth solution " << score(temp, rides, b)< bestscore){ bestscore = tempscore; best = temp; } } { const auto& temp = fourthSolution<3>(cars, rides, firstSolution); cerr << "fourth solution " << score(temp, rides, b)< bestscore){ bestscore = tempscore; best = temp; } } //const auto& sol2 = secondSolution(cars, rides, 0.95f); cerr << "best score: " << score(best, rides, b) << endl; for(const auto& car : best){ cout << car.rides.size() << ' '; for(int i : car.rides) cout << i << ' '; cout << '\n'; } return 0; }