POJ 1949 [最小优先队列]

  题意是有N行任务,给出完成每项任务所需要的时间长度,求出完成所有任务所需要的最短时间.每个任务都会有一个约束条件,就是在完成这项任务之前必须完成所列出的其它任务.可以同时做多项任务.简单来说就像煮饭炒菜问题一样,可以一边烧饭一边炒菜.但炒菜之前必先洗菜.

  这道题我主要用了最小优先队列,有点像dijktra, 列队按两个条件来维护, 首先是所按所需的条件(前任务)个数,这里用Need[]数组保存,然后按开始任务的时间. 用一个Need[]数组维护每个任务所需的前任务个数,如果为0, 则丢进列队里, 每次取出列队首元素, 即当前可以开始的任务, 将所有以这一任务为前提的任务的Need减一,再更新一下start值(表示任务开始的时间). 若Need为0,则丢进列队里,如此重复直到列队为空, 再找出start里最大值,再加上这个最大start值的任务的所需时间,即为完成所有任务所需的最短时间.

代码
1 #include <iostream>
2 #include <cstdio>
3 #include <string>
4 #include <cstring>
5 #include <vector>
6 #include <queue>
7 #include <algorithm>
8
9  using namespace std;
10
11 const int MAXN=10001;
12 const int INF=0x7f7f7f7f;
13
14 vector<int> Box[MAXN];
15 int Cost[MAXN], Start[MAXN], Need[MAXN];
16
17 void init_input(const int n)
18 {
19 int num, temp;
20 memset(Start, 0x7f, sizeof(Start));
21 //printf("%d\n", Start[0]);
22 for( int i=0; i<n; ++i )
23 {
24 scanf("%d%d", &Cost[i], &num);
25 //cin>>Cost[i]>>num;
26 Need[i]=num;
27 while( num-- )
28 {
29 scanf("%d", &temp);
30 Box[temp-1].push_back(i);
31 }
32 }
33 }
34 void clear(const int n)
35 {
36 for( int i=0; i<n; ++i )
37 Box[i].clear();
38 }
39
40 class comp
41 {
42 public:
43 bool operator()(const int i, const int j)
44 {
45 if( Need[i] == Need[j] )
46 return Start[i] > Start[j];
47 else
48 return Need[i] > Need[j];
49 }
50 };
51
52 int solve(const int n)
53 {
54 priority_queue<int, vector<int>, comp> que;
55 for( int i=0; i<n; ++i )
56 {
57 if( Need[i] == 0 )
58 {
59 Start[i]=0;
60 que.push(i);
61 }
62 }
63 int ans=0;
64 while( !que.empty() )
65 {
66 int front=que.top();
67 que.pop();
68 //printf("%d\n", front);
69 vector<int>::iterator ix=Box[front].begin();
70 while( ix != Box[front].end() )
71 {
72 Need[*ix]--;
73 //printf("%d\n", *ix);
74 if( Start[*ix] == INF || Start[*ix] < Start[front]+Cost[front] )
75 {
76 Start[*ix] = Start[front]+Cost[front];
77 }
78 if( Need[*ix] == 0 )
79 que.push(*ix);
80 ++ix;
81 }
82 }
83 for( int i=0; i<n; ++i )
84 {
85 ans=Start[i]+Cost[i]>ans?Start[i]+Cost[i]:ans;
86 }
87 return ans;
88 }
89
90 int main()
91 {
92 freopen("in", "r", stdin);
93 freopen("out", "w", stdout);
94
95 int n;
96 while( cin>>n )
97 {
98 init_input(n);
99 printf("%d\n", solve(n));
100 clear(n);
101 }
102 return 0;
103 }
104
posted on 2010-11-20 14:42  Kenfly  阅读(598)  评论(0)    收藏  举报