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

来源:互联网 发布:级域名泛解析多久生效 编辑:程序博客网 时间:2024/04/26 07:56

这题的题意就是给你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 longusing 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;}


原创粉丝点击