题意:K个数组每组K个值,每次从一组中选一个,共K^k种,问前K个小的。
思路:优先队列处理多路归并,每个状态含有K个元素。详见刘汝佳算法指南。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<stack> 5 #include<queue> 6 #include<vector> 7 #include<map> 8 #include<algorithm> 9 using namespace std; 10 int n; 11 int a[1000][1000]; 12 int b[1000]; 13 int c[1000]; 14 15 struct Item 16 { 17 int s,b; 18 Item(int s,int b):s(s),b(b) 19 { 20 } 21 bool operator < (const Item& rhs) const 22 { 23 return s>rhs.s; 24 } 25 }; 26 void merge(int *a,int *b,int *c,int n) 27 { 28 priority_queue<Item>q; 29 for(int i=0; i<n; i++) 30 q.push(Item(a[i]+b[0],0)); 31 for(int i=0; i<n; i++) 32 { 33 Item item =q.top(); 34 q.pop(); 35 c[i]=item.s; 36 int B=item.b; 37 if(B+1<n) 38 q.push(Item(item.s-b[B]+b[B+1],B+1)); 39 } 40 } 41 42 int main() 43 { 44 while(~scanf("%d",&n)) 45 { 46 for(int i=0; i<n; i++) 47 { 48 for(int j=0; j<n; j++) 49 scanf("%d",&a[i][j]); 50 sort(a[i],a[i]+n); 51 } 52 for(int i=1; i<n; i++) 53 merge(a[0],a[i],a[0],n); 54 printf("%d",a[0][0]); 55 for(int i=1; i<n; i++) 56 printf(" %d",a[0][i]); 57 printf("\n"); 58 } 59 return 0; 60 }