POJ3553 Task schedule (拓撲排序+優先隊列)經典


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 ≤ ij ≤ 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);
    }
}



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com