We just need to define a comparison struct for ListNodes, then managing the priority_queue is quite straightforward. After filling the priority_queue, if it is non-empty, we set the head and tail. Then we repeatedly pop the top off the queue and append that to the tail. If the next node is not null, we push it onto the queue.

```
class Solution {
struct compare {
bool operator()(const ListNode* l, const ListNode* r) {
return l->val > r->val;
}
};
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
priority_queue<ListNode *, vector<ListNode *>, compare> q;
for (auto l : lists) {
if (l) {
q.push(l);
}
}
if (q.empty()) {
return NULL;
}
ListNode* result = q.top();
q.pop();
if (result->next) {
q.push(result->next);
}
ListNode* tail = result;
while (!q.empty()) {
tail->next = q.top();
q.pop();
tail = tail->next;
if (tail->next) {
q.push(tail->next);
}
}
return result;
}
};
```