POJ 3553 Task schedule(拓扑排序)

本文深入探讨了EDF(最早截止时间优先)非抢占式作业调度算法在解决任务调度问题中的应用。通过分析如何最小化任务超时风险,文章详细解释了算法的工作原理,并提供了一段C++代码实现,展示了如何根据截止日期对任务进行优先级排序,以确保任务在截止日期前完成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

http://poj.org/problem?id=3553

题意:

给定一些工作,第一行n代表n个共工作,2-n+1行每行两个数字Pj和Dj,代表每个工作的截至完成时间以及完成工作所要花费的时间;第n+2行一个m,下面m行每行一个关系(x,y)代表x需要在y之前完成;求出任务的完成顺序的编号,并且最小化每个任务的max(Ci-Di,0)(Ci代表从开始到i任务的完成时间);

分析:

对于max(Ci-Di,0),如果一个任务超时完成,即Ci>Di那么i任务的max(Ci-Di,0)等于Ci-Di,否则就等于0,所以我们应该尽可能考虑让每个任务都在它的截至日期之前完成;这其实就是EDF非抢占式作业调度算法,那么对于队列中的job我们应该优先考虑截止日期考前的完成;

代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;

#define  inf 0x7f7f7f7f
#define  maxn 100411
#define  N 500050
#define mod 100003

typedef long long ll;
typedef struct{
    int u,v,next,w;
}Edge;
Edge e[N];
int cnt,head[N];

inline void add(int u,int v){
    e[cnt].u=u;
    e[cnt].v=v;
    //e[cnt].w=w;
    // e[cnt].f=f;
    e[cnt].next=head[u];
    head[u]=cnt++;
    //e[cnt].u=v;
//    e[cnt].v=u;
//    e[cnt].w=0;
//    e[cnt].f=-f;
//    e[cnt].next=head[v];
//    head[v]=cnt++;
}
inline void write(int x)
{
    if(x<0)
        putchar('-'),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}

inline int read(){
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')
            f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
 struct job{
     int d,x;
     bool operator<(const job & t)const{
         return d>t.d;
     }
 };
 job j[50050];
int num,n,m,in[50050],top[50050];

void topsort(){
    priority_queue<job>q;
    for(int i=1;i<=n;i++){
        if(!in[i])
            q.push(j[i]);
    }
    while(!q.empty()){
        job u=q.top();q.pop();
        top[num++]=u.x;
        for(int i=head[u.x];i!=-1;i=e[i].next){
            int v=e[i].v;
            in[v]--;
            if(!in[v])q.push(j[v]);
        }
    }
    for(int i=0;i<num-1;i++){
        cout<<top[i]<<endl;
    }
    cout<<top[num-1];
}
int main() {
    cin>>n;
    int p;
    for(int i=1;i<=n;i++){
        int p;
        cin>>p>>j[i].d;
        j[i].x=i;
    }
    cin>>m;
    int x,y;
    memset(head,-1,sizeof(head));
    for(int i=0;i<m;i++){
        scanf("%d%d",&x,&y);
        add(x,y);
        in[y]++;
    }
    topsort();
    return 0;
}

我们坚持一件事情,并不是因为这样做了会有效果,而是坚信,这样做是对的。
——哈维尔

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值