Input
n
number of workers and m
jobs to be scheduled, followed by m
lines of time t
taken by a particular job to be completed.
workers(or threads) take jobs in the order they are given in the input. If there is a free thread, it immediately takes the next job from the list. If a thread has started processing a job, it doesn’t interrupt or stop until it finishes processing the job. If several threads try to take jobs from the list simultaneously, the thread with smaller index takes the job. For each job you know exactly how long will it take any thread to process this job, and this time is the same for all the threads. You need to determine for each job which thread will process it and when will it start processing.
Output
m
lines. i-th
line containing two space-separated integers - 0 based index of the thread which will process the i-th
job and its start time
Constraints
0 ≤ n ≤ 105 (number of workers)
0 ≤ m ≤ 105 (number of jobs)
0 ≤ t ≤ 109 (time taken for each job)
My Approach
I have used a heap to represent a priority queue of the threads to determine the next worker. The workers are first prioritized by their next free time
and then by their index
. To represent these two quantities I've used the pair
in c++ stl.
Here is my code:
#include <algorithm> #include <iostream> #include <vector> using std::cin; using std::cout; using std::make_pair; using std::pair; using std::swap; using std::vector; class JobQueue { private: int num_workers_; vector<int> jobs_; vector<int> assigned_workers_; vector<long long> start_times_; void WriteResponse() const { for (int i = 0; i < jobs_.size(); ++i) { cout << assigned_workers_[i] << " " << start_times_[i] << "\n"; } } void ReadData() { int m; cin >> num_workers_ >> m; jobs_.resize(m); for (int i = 0; i < m; ++i) cin >> jobs_[i]; } void heapify(vector<pair<int, long long>> &heap, int k) { int smallest = k; int left = (2 * k) + 1; int right = (2 * k) + 2; if (left < heap.size()) { if (heap[left].second < heap[smallest].second) smallest = left; else if (heap[left].second == heap[smallest].second) { if (heap[left].first < heap[smallest].first) smallest = left; } } if (right < heap.size()) { if (heap[right].second < heap[smallest].second) smallest = right; else if (heap[right].second == heap[smallest].second) { if (heap[left].first < heap[smallest].first) smallest = right; } } if (left < heap.size() && right < heap.size() && heap[left].second == heap[right].second) { if (heap[left].first < heap[right].first) smallest = left; else smallest = right; } if (smallest != k) { swap(heap[k], heap[smallest]); heapify(heap, smallest); } } void changePriority(vector<pair<int, long long>> &heap, int incr) { heap[0].second += incr; heapify(heap, 0); } void AssignJobs() { assigned_workers_.resize(jobs_.size()); start_times_.resize(jobs_.size()); vector<pair<int, long long>> next_free_time(num_workers_); for (int i = 0; i < num_workers_; i++) { next_free_time[i].first = i; next_free_time[i].second = 0; } for (int i = 0; i < jobs_.size(); ++i) { pair<int, long long> next_worker = next_free_time[0]; assigned_workers_[i] = next_worker.first; start_times_[i] = next_worker.second; changePriority(next_free_time, jobs_[i]); } } public: void Solve() { ReadData(); AssignJobs(); WriteResponse(); } }; int main() { std::ios_base::sync_with_stdio(false); JobQueue job_queue; job_queue.Solve(); return 0; }
Complexity
if J
is the number of jobs and T
the number of threads, the complexity here (I might be wrong, please correct me if I am) should be O(J log T)
Question
The code exceeds time limit in certain cases, how can I optimize it? (Time limit: 1 sec)