```
import java.io.*;
import java.util.ArrayList;public class Main{
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] s = reader.readLine().split(" ");
int m = Integer.valueOf(s[0]);
int k = Integer.valueOf(s[1]);
int[][] matrix = new int[m][];
for(int i = 0;i<m;i++){
s = reader.readLine().split(" ");
int n = Integer.valueOf(s[0]);
matrix[i] = new int[n];
for(int j = 0;j<n;j++)
matrix[i][j] = Integer.valueOf(s[j+1]);
}
getTopK(matrix,k);
}
static class HeapNode{
int index;
int arrIndex;
int num;
HeapNode( int arrIndex, int index, int num){
this.arrIndex = arrIndex;
this.index = index;
this.num = num;
}
}
static void swap(HeapNode[] heap,int p,int i){
HeapNode tmp = heap[p];
heap[p] = heap[i];
heap[i] = tmp ;
}
static void heapInsert(HeapNode[] heap,int i){
int parent = (i-1) / 2;
while(i >=0 && heap[parent].num < heap[i].num){
swap(heap,parent,i);
i = parent;
parent = (i-1) / 2;
}
}
static void heapify(HeapNode[] heap,int index,int heapSize){
int left = index * 2 + 1;
int right = index * 2 + 2;
int largest = index;
// 这里设计成为< 因为heapSize一直都是右开
while(left < heapSize){
if(heap[left].num > heap[largest].num)
largest = left;
if(right<heapSize && heap[right].num > heap[largest].num)
largest = right;
if(index!=largest)
swap(heap,largest,index);
else
return ;
index = largest;
left = largest * 2 + 1;
right = largest * 2 + 2;
}
}
static void getTopK(int[][] matrix,int k){
// System.out.print("hello");
int heapSize = matrix.length;
HeapNode[] heap = new HeapNode[heapSize];
for(int i = 0;i<heapSize;i++){
int length = matrix[i].length ;
heap[i] = new HeapNode(i,length-1,length==0?-1:matrix[i][length-1]);
heapInsert(heap,i);
}
//这里已经构造了一个大顶堆
for(int i = 0;i<k;i++){
System.out.print(heap[0].num+" ");
if(heap[0].index==0){
//因为少了一列 所以可以看少一个heapSize 把最开始的 和最后一个交换 不管后面那些了
swap(heap,0,--heapSize);
}else{
heap[0].num = matrix[heap[0].arrIndex][--heap[0].index];
}
heapify(heap,0,heapSize);
}
}
}
```