第十二届蓝桥杯省赛第二场 C++ B组 - 负载均衡(优先队列维护结构体)

文章介绍了如何使用优先队列来解决动态任务分配问题,特别是如何重载结构体以适应大顶堆或小顶堆的需求。在计算机运算能力有限的情况下,任务按照时间戳排序并分配,如果运算能力不足则返回错误。代码示例展示了如何实现这一过程。
摘要由CSDN通过智能技术生成

题目:
有 n 台计算机,第 i 台计算机的运算能力为 vi。
有一系列的任务被指派到各个计算机上,第 i 个任务在 ai 时刻分配,指定计算机编号为 bi,耗时为 ci 且算力消耗为 di。
如果此任务成功分配,将立刻开始运行,期间持续占用 bi 号计算机 di 的算力,持续 ci 秒。
对于每次任务分配,如果计算机剩余的运算能力不足则输出 −1,并取消这次分配,否则输出分配完这个任务后这台计算机的剩余运算能力。

题解:
就是动态维护a的排序,所以想到堆。然后发现我不会优先队列维护结构体,于是学了一下。
优先队列维护结构体好像就是要把结构体重载一下,然后在直接套优先队列里面。

优先队列维护结构体代码:

typedef struct point
{
    ll a,b,c,d;
    int flag;
    bool friend operator < (struct point A,struct point B){ //重载小于号
        if(A.a==B.a) return A.flag>B.flag;
        else return A.a>B.a;
    }
};
/*这里重载小于号为大于号,这样排序的时候如果是从小到大排,就会变成从大到小排。同理,如果把小于号重载为小于号,那么排序的时候怎么排,就不会变成相反的顺序。*/
priority_queue<point>Q;//就直接设。优先队列直接设的话默认是用vector,大顶堆。

研究了一下发现大顶堆结构体只能重载小于号,小顶堆结构体只能重载大于号,要是想用小顶堆也可以这样写:

typedef struct point
{
    ll a,b,c,d;
    int flag;
    bool friend operator > (struct point A,struct point B){ //重载大于号
        if(A.a==B.a) return A.flag>B.flag;
        else return A.a>B.a;
    }
};

priority_queue<point,vector<point>,greater<point> >Q;//小顶堆

然后完全代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6;
typedef struct point
{
    ll a,b,c,d;
    int flag;
    bool friend operator < (struct point A,struct point B){ //重载小于号
        if(A.a==B.a) return A.flag>B.flag;
        else return A.a>B.a;
    }
};

int main(){
    int n,m;
    scanf("%d%d",&n,&m);
 //   printf("n=%d m=%d\n",n,m);
    ll B[n+10];
    for(int i=1;i<=n;i++){
        scanf("%lld",&B[i]);
    }
    priority_queue<point>Q;
    point temp;
    temp.flag=1;
    for(int i=0;i<m;i++){
        scanf("%lld%lld%lld%lld",&temp.a,&temp.b,&temp.c,&temp.d);
        Q.push(temp);
    }
    while(!Q.empty()){
        point temp2;
        temp2=Q.top();
        Q.pop();
        ll a,b,c,d;
        a=temp2.a;
        b=temp2.b;
        c=temp2.c;
        d=temp2.d;
     //   printf("%lld %lld %lld %lld %lld\n",a,b,c,d,temp2.flag);
        if(temp2.flag){
            if(d>B[b]) printf("-1\n");
            else{
                B[b]=B[b]-d;
                temp2.a=a+c;
                temp2.flag=0;
                Q.push(temp2);
                printf("%lld\n",B[b]);
            }
        }
        else{
            B[b]=B[b]+d;
        }
    
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值