POJ 3553 Task schedule

  原题链接:http://poj.org/problem?id=3553

  这道题主要就是贪心思想吧,对于每个job,根据其截止时间 d从小到大排序,我们必须要尽快把dj最小的job完成掉,这样才能使max{Cj-dj, 0}最小(因为对于最小dj在没完成该工作时dj使不变的,如果你先做了其他没关联的工作,只会使Cj变大,从而使max{Cj-dj, 0}变大,这和题目所求刚好相反了)。因为要完成dj工作会需要先完成其他工作,那么这时候dfs一下,一步一步找到其祖先打印出来即可。

  网上有人用的拓扑排序+贪心,我表示没看懂。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <vector>
 4 #include <queue>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 50000 + 5;
 9 int n, m;
10 
11 struct node
12 {
13     int p;
14     int d;
15     int id;
16 }job[maxn];
17 
18 vector<int> V[maxn];
19 bool vis[maxn];
20 
21 bool cmp(node a, node b)
22 {
23     return a.d < b.d;
24 }
25 
26 void dfs(int cur)
27 {
28     if(vis[cur])
29         return ;
30     vis[cur] = true;
31     int k = V[cur].size();
32     for(int i = 0; i < k; i++)
33         dfs(V[cur][i]);
34     printf("%d\n", cur);
35 }
36 
37 void init()
38 {
39     memset(vis, false, sizeof vis);
40     for(int i = 1; i <= n; i++)
41         V[i].clear();
42 }
43 
44 int main()
45 {
46     int a, b;
47     while(scanf("%d", &n) != EOF)
48     {
49         init();
50         for(int i = 1; i <= n; i++)
51         {
52             scanf("%d%d", &job[i].p, &job[i].d);
53             job[i].id = i;
54         }
55         sort(job+1, job+n+1, cmp);
56         scanf("%d", &m);
57         for(int i = 1; i <= m; i++)
58         {
59             scanf("%d%d", &a, &b);
60             V[b].push_back(a);
61         }
62         for(int i = 1; i <= n; i++)
63             if(!vis[job[i].id])
64                 dfs(job[i].id);
65     }
66     return 0;
67 }
View Code

 

  

posted @ 2013-07-26 20:14  芒果布丁  阅读(458)  评论(0编辑  收藏  举报