您的位置:首页 > 其它

Uva11997 优先级队列的应用 多路合并问题

2013-08-25 13:01 423 查看
这题的题意就是给你k个数组,没个数组里有k个值,然后让你求从这k个数组中取一个数,所得的前k个最小的和。

这里应用到了优先级队列,先合并两个数组,求出最小的k个和,然后依次合并其他数组。

这里对于优先级队列的内部函数写的还是不很熟练,以后应该会好点。

代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<queue>
#include<algorithm>
#include<cstring>
#define maxn 1000
#define INF 0xfffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR(i,s,t) for(int i=s;i<=t;i++)
#define ull unsigned long long
#define ll long long
using namespace std;
struct Item
{
    int s,b;//s=A[i]+B[b];
    Item(int s,int b):s(s),b(b){}
    bool operator < (const Item& it)const//注意这里是const&
    {
        return s>it.s;
    }
};
void merge(int *A,int *B,int *C,int n)//注意这里的A和B都是有序的
{
    priority_queue<Item> q;
    for(int i=0;i<n;i++)
    {
        q.push(Item(A[i]+B[0],0));
    }
    for(int i=0;i<n;i++)
    {
        Item it=q.top();q.pop();
        C[i]=it.s;
        int b=it.b;
        if(b+1<n)
        {
            q.push(Item(it.s-B[b]+B[b+1],b+1));
        }
    }
}
int A[maxn][maxn];
int main()
{
    int n;
    while(scanf("%d",&n)==1)
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                scanf("%d",&A[i][j]);
            }
            sort(A[i],A[i]+n);
        }
        for(int i=1;i<n;i++)//两两结合
        {
            merge(A[0],A[i],A[0],n);
        }
        for(int i=0;i<n;i++)
        {
            if(!i)
            printf("%d",A[0][i]);
            else
            printf(" %d",A[0][i]);
        }
        printf("\n");
    }
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: