题意:
有n个任务,每个任务完成都有其所需的时间,并且有其前置任务,问完成所有任务要多久(没有直接关系的任务可以同时开始)
思路:
自己写的稍稍有些复杂
首先建图,对于一个任务给所有其前置任务连一条有向边(从前置连向自己),并记录一个点的入读
之前遍历一遍,将入度为0的点加入队列中,边将其所有相邻的点入度减一,如果有入度为0的点,则加入队列中
比较关键的一点就是如何更新时间dp[nex]=max(dp[nex],dp[i]+tim[nex])
我的写法较为复杂,还多用了一个队列存时间,用一个DP数组就能直接解决了
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e5+10;
queue<int> a,b;
vector<int> edge[maxn];
int in[maxn],tim[maxn],ans,n,mx[maxn];
void solve()
{
for(int i=1;i<=n;i++){
if(!in[i]){
a.push(i),b.push(tim[i]);
}
}
while(!a.empty()){
int x=a.front(),y=b.front();
a.pop(),b.pop();
ans=max(ans,y);
for(int i=0;i<edge[x].size();i++){
in[edge[x][i]]--;
mx[edge[x][i]]=max(y,mx[edge[x][i]]);
if(!in[edge[x][i]]){
a.push(edge[x][i]);
b.push(tim[edge[x][i]]+mx[edge[x][i]]);
}
}
}
}
int main()
{
int x,y,temp;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
tim[x]=y;
while(scanf("%d",&temp)&&temp){
edge[temp].push_back(x);
in[x]++;
}
}
memset(mx,-inf,sizeof(mx));
ans=-inf;
solve();
cout<<ans<<endl;
}
来源:https://www.cnblogs.com/overrate-wsj/p/12309442.html