一道拓扑排序的板子题,因为我们可以先记录一下每个点是受到哪几个点的影响,因为只有这些点的工作完成了才能完成这个工作 就可以想到用拓扑排序了。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N],d[N],nt[N];
queue<int> q;
vector<int > h[N];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>i;
cin>>a[i];
int t;
while (cin>>t,t) {
h[t].push_back(i);//统计这个点与那些点相连
d[i]++;//这个点就增加一入度;
}
}
for(int i=1;i<=n;i++)
if(!d[i]) {
nt[i]=a[i];//这个点完成耗费的总时间
q.push(i);//找到那入度为0的点
}
while (q.size()){
auto t=q.front();
q.pop();
for(int i=0;i<h[t].size();i++){
int j=h[t][i];
nt[j]= max(nt[j],a[j]+nt[t]);//更新当前耗费时间;
if(--d[j]==0) q.push(j);//只有与他相连的所有工作完成了才能做这个工作
}
}
int ma=0;
for(int i=1;i<=n;i++) ma=max(ma,nt[i]);
cout<<ma;
return 0;
}
这个也可以dp,因为每个点的前提工作都小于自己那么只需要考虑最大的那个点的耗费时间就可以了
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N],n,ansmax;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
int m,t,t1;
cin>>i>>t;
int tm=0;
while (cin>>t1,t1) tm=max(a[t1],tm);//记录前提工作的最大耗费时间;
a[i]=tm+t;//更新自己的总耗费时间
ansmax= max(a[i],ansmax);//更新最大耗费时间
}
cout<<ansmax;
return 0;
}