题目:
有 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;
}