#include <iostream>
#include <queue>
#include <stdio.h>
using namespace std;
int main(int argc, const char * argv[])
{
int cas,n,m,t;
priority_queue<int,vector<int>,greater<int> >Q0;
priority_queue<int,vector<int>,less<int> >Q1;
int tmp_arr[2001],arr[2001];
cin >> cas;
while (cas--) {
cin >> m >> n;
for (int j=0; j<n; j++) {
cin>>t;
Q0.push(t);
}
while (--m) {
int i=0;
for (int j=0; j<n; j++)
cin>>arr[j];
while (!Q0.empty()) {
tmp_arr[i++]=Q0.top();
Q0.pop();
}
for (int j=0; j<n; j++)
Q1.push(tmp_arr[j]+arr[0]);
for (int j=1; j<n; j++) {
for (int k=0; k<n; k++) {
if (tmp_arr[k]+arr[j]>=Q1.top())
break;
Q1.push(tmp_arr[k]+arr[j]);
}
for (int j=Q1.size(); j>n; j--)
Q1.pop();
}
while (!Q1.empty()) {
Q0.push(Q1.top());
Q1.pop();
}
}
for (int j=0; j<n; j++) {
j&&putchar(' ');
cout<<Q0.top();
Q0.pop();
}
puts("");
}
return 0;
}
通过带入下个数组,刷新最小的n个元素,维护堆的大小为n!
其中的诡异代码是在刷新过程中要一直保持队列大小为n,这样子就可以通过tmp_arr[k]+arr[j]>=Q1.top() 剪枝,因为当Q1.top()越小,剪枝越明显!!如果不理Q1大小,而在最后刷新完之后,再恢复,那么中间的剪枝就没用了!!!!我sb了。。