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

你可能感兴趣的:(优先队列)