【洛谷习题】杂务

题目链接:https://www.luogu.org/problemnew/show/P1113


打眼一看,这不就是道拓扑排序的问题?不过和一般的拓扑排序不同,这里不只是要求一个完成工作的次序,每个工作都有相应的完成所需时间,要求完成所有工作所需的最短时间。之所以这里会有最短时间,是因为已完成准备工作的任务可以同时进行,只要每项工作能完则完,那么最终所有工作都完成所需的时间就是最短的(废话)。还是拓扑排序的思路,只需要这样想,设定一个early数组表示每项工作的最早开始时间,他就等于该工作所有准备工作中,完成最晚的。答案就是整个过程中所经历过最晚的完成时间。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<cstring>
 4 #include<queue>
 5 #include<algorithm>
 6 using namespace std;
 7 inline int get_num() {
 8     int num;char c;
 9     while((c=getchar())=='\n'||c==' '||c=='\r');
10     num=c-'0';
11     while(isdigit(c=getchar())) num=num*10+c-'0';
12     return num;
13 }
14 const int maxn=1e4+5,maxm=1e6+5;
15 int n,len[maxn],head[maxn],eid,ind[maxn],early[maxn],ans;
16 struct edge {
17     int v,next;
18 } E[maxm];
19 void insert(int u,int v) {
20     E[eid].v=v;
21     E[eid].next=head[u];
22     head[u]=eid++;
23 }
24 queue<int> q;
25 int main() {
26     n=get_num();
27     memset(head,-1,sizeof(head));
28     int in,new_t;
29     for(int i=1;i<=n;++i) {
30         get_num();len[i]=get_num();
31         while((in=get_num())) insert(in,i),++ind[i]; //注意是有一条从in到i的边
32         if(!ind[i]) q.push(i);
33     }
34     while(!q.empty()) { //队列中存放当前入度为0的点
35         int u=q.front();q.pop();
36         new_t=early[u]+len[u];
37         ans=max(ans,new_t); //统计答案
38         for(int p=head[u];p+1;p=E[p].next) {
39             int v=E[p].v;
40             early[v]=max(early[v],new_t); //更新每项工作的最早开始时间
41             if(!(--ind[v])) q.push(v);
42         }
43     }
44     printf("%d",ans);
45     return 0;
46 }
AC代码

猜你喜欢

转载自www.cnblogs.com/Mr94Kevin/p/9580286.html
今日推荐