POJ-2442-Sequence(二叉堆)

POJ-2442

Description

Given m sequences, each contains n non-negative integer. Now we may select one number from each sequence to form a sequence with m integers. It's clear that we may get n ^ m this kind of sequences. Then we can calculate the sum of numbers in each sequence, and get n ^ m values. What we need is the smallest n sums. Could you help us?

Input

The first line is an integer T, which shows the number of test cases, and then T test cases follow. The first line of each case contains two integers m, n (0 < m <= 100, 0 < n <= 2000). The following m lines indicate the m sequence respectively. No integer in the sequence is greater than 10000.

Output

For each test case, print a line with the smallest n sums in increasing order, which is separated by a space.

Sample Input

1

2 3

1 2 3

2 2 3

Sample Output

3 3 4

题意:给M个数量为N的序列,从每个序列中任取一个数求和,可以构成N^M个和,求其中最小的N个和。

分析:

  • 两组两组的看,首先要排序,然后从头开始找最小的N个和。
  • 怎么找是个问题,对于第一组我们取i=1,第二组取j=1,然后a[1]+b[1]肯定是最小的,然后a[2]+b[1],a[1]+b[2]进入候选项,如果我们下一次选中了a[2]+b[1],那么我们又要将a[3]+b[1],a[2]+b[2]加入候选项。
  • 但是我们要保证产生候选项不能重复,比如a[1]+b[2]和a[2]+b[1]都可以产生a[2]+b[2],所以我们要排除其中的一种,也就是说,我们要将候选项的下标计算变得有限制。
  • 候选项的下标都是通过选中当前项的下标加一得到的,那么为了避免重复,我们要制定一种规则。假如规定为如果j+1,那么这个候选项被选中的时候i就不能更新。
  1. i=1,j=1
    • 更新i=2,j=1, flag = true
    • 更新i=1, j=2, flag = false
  2. 假如选中i=2,j=1,flag = true
    • 由于是true,可以更新i=3,j=1,flag = true
    • 更新i=2,j=2,flag = false
  3. 假如选中i=1,j=2,flag = false
    • 由于false,不能更新i
    • 更新i=1,j=3,flag = false
      ......
#define MAX 2001
#define MAXM 101
int n,m;
int a[MAXM][MAX];
struct node
{
	int i,j;
	int val;
	bool model;
	bool operator<(const node&a)const
	{
		return val>a.val;
	}
};
int main() 
{
	int T;
	cin>>T;
	for(int r=0;r<T;r++)
	{
		cin>>m>>n;
		for(int i=0;i<m;i++)
   		{
   			for(int j=0;j<n;j++)
   				scanf("%d",&a[i][j]);
   			sort(a[i],a[i]+n);
   		}
   		int tmp[MAX];
   		node temp;
   		memcpy(tmp,a[0],sizeof(int)*n);
   		for(int k=1;k<m;k++)
   		{
   			int i=0,j=0,c=0,val = tmp[0]+a[k][0];
   			bool flag = 1;
   			priority_queue<node> q;
   			while(c<n)
   			{
   				a[0][c++] =val;
   				if(flag)
   				{
   					temp.i = i+1,temp.j = j,temp.val = tmp[i+1]+a[k][j],temp.model = true;
   					q.push(temp);
   				}
   				temp.i = i,temp.j = j+1,temp.val = tmp[i]+a[k][j+1],temp.model = false;
   				q.push(temp);
   				i = q.top().i,j = q.top().j,val = q.top().val,flag = q.top().model;
   				q.pop();
   			}
   			for(int i=0;i<n;i++)
   			{
   				tmp[i] = a[0][i];
   			}
   		}
   		printf("%d",tmp[0]);
   		for(int i=1;i<n;i++)
   			printf(" %d",tmp[i]);
   		puts("");
	}
    return 0;
}
posted @ 2018-08-14 16:39  kpole  阅读(229)  评论(0编辑  收藏  举报