POJ 3553 Task schedule
原题链接:http://poj.org/problem?id=3553
这道题主要就是贪心思想吧,对于每个job,根据其截止时间 dj 从小到大排序,我们必须要尽快把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 }