Task schedule
Time Limit: 2000MS | Memory Limit: 65536K | |||
Total Submissions: 306 | Accepted: 193 | Special Judge |
Description
There are n preemptive jobs to be processed on a single machine. Each job j has a processing time pj and deadline dj. Preemptive constrains are specified by oriented graph without cycles. Arc (i,j) in this graph means that job i has to be processed before job j. A solution is specified by a sequence of the jobs. For any solution the completion time Cj is easily determined.
The objective is to find the optimal solution in order to minimize
max{Cj–dj, 0}.
Input
The first line contains a single integer n, 1 ≤ n ≤ 50000. Each of the next n lines contains two integers pj and dj, 0 ≤ pj ≤ 1000, 0 ≤ dj ≤ 1000000, separated by one or more spaces. Line n+2 contains an integer m (number of arcs), 0 ≤ m ≤ 10*n. Each of the next m lines contains two integers i and j, 1 ≤ i, j ≤ n.
Output
Each of the n lines contains integer i (number of job in the optimal sequence).
Sample Input
2 4 1 4 0 1 1 2
Sample Output
1 2
Source
Northeastern Europe 2003, Western Subregion 题意看了好久都没能明白,最后终于理解了。 在网上看到的都是用 贪心算法+DFS 过的。 题意:完成所有的任务后,问 怎样按照一定的时间先后顺序去完成所有任务(每个任务有一个完成处理的时间,只有一台机器,且机器每次只能处理一个任务,m对 (i j) 表要想完成 j 任务,则先完成 i 任务),使得所有情况中min{
max{
Cj
–
dj
, 0}}的值最小。输出一个完成任务的先后顺序,满足情况可能有多种,只要输出其中一种即可。
解题:我们可以反向思考,最后完成所有任务的总时间是确定的,那么只要判断哪一任务在最后处理(最后处理的任务有 一特点:出度为0),要想
max{
Cj
–
dj
, 0}最小,则找出度为0的dj 最大的点,当确定了一个最终输出的点后,就可以把该点及有关的信息在图中删除,之后重复上述步骤一个一个确定点,最后得到一个序列。那么我们只要反向建图,则出度为0的点变成了入度为0的点,用优先队列处理,从队列中取出的点,先用数组存入,最后处理完了,逆向输出序列。
#include<stdio.h>
#include<queue>
#include<vector>
using namespace std;
const int N = 50005 ;
struct node
{
int id,d;
friend bool operator<(node a,node b)
{
return b.d>a.d;
}
};
vector<int>mapt[N];
int path[N],in[N],d[N];
void print(int n)
{
while(n--)
{
printf("%d\n",path[n]);
}
}
void tope(int n)
{
int k=0;
priority_queue<node>q;
node pre,now;
for(int i = 1; i <= n; i++)
if(in[i]==0)
{
now.d = d[i]; now.id = i; q.push(now);
}
while(!q.empty())
{
pre = q.top(); q.pop();
path[k++] = pre.id;
int len = mapt[pre.id].size();
for(int i = 0 ;i < len; i++)
{
now.id = mapt[pre.id][i];
now.d = d[now.id];
in[now.id]--;
if(in[now.id]==0)
{
q.push(now);
}
}
}
print(k);
}
int main()
{
int n,m,a,b;
while(scanf("%d",&n)>0)
{
for(int i = 1; i <= n; i++)
{
scanf("%d%d",&a,&d[i]);
in[i] = 0;
mapt[i].clear();
}
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&a,&b);
mapt[b].push_back(a);
in[a]++;
}
tope(n);
}
}