一道拓扑排序的模板题
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;
const int maxn=1e4+10;
int n,ans;
bool e[maxn][maxn];//bool数组占用内存不大
queue<int> q;
int mx[maxn],ti[maxn],ru[maxn];
void topo(){
for(int i=1;i<=n;i++)
if(!ru[i]){//寻找入度为0,加入队列中
q.push(i);
mx[i]=ti[i];//最早完成的时间
}
while(!q.empty()){
int d=q.front();
q.pop();
for(int i=1;i<=n;i++){
if(e[d][i]){//如果有关系
ru[i]--;//第i项入度减1
if(!ru[i])q.push(i);//入度为0,加入队列中
mx[i]=max(mx[i],mx[d]+ti[i]);
//假如c1、c2是c3的前驱,c3完成的时间肯定是c1、c2较晚的时间加上c3的时间
}
}
}
for(int i=1;i<=n;i++)
ans=max(ans,mx[i]);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int a,b,c;//a为工作序号,b是所需时间,c必须完成的工作
scanf("%d%d%d",&a,&b,&c);
ti[a]=b;//记录每一项工作所需要的时间
while(c){
ru[a]++;//入度
e[c][a]=true;//前驱和后继的关系
scanf("%d",&c);
}
}
topo();//拓扑排序
printf("%d\n",ans);
return 0;
}
还有一种思路是DP/
题目中已经说了第k(k>1)项工作,准备工作只在1到k-1项工作里
而每一项工作要完成的时间是,最晚的前驱加上自己的时间
这道题其实求的是,完成最后一个需要的时间
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
int s[maxn];
int n,sum;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int a,b,c;
int temp=0;
scanf("%d%d",&a,&b);
while(scanf("%d",&c)&&c){
temp=max(temp,s[c]);
}
s[i]=temp+b;
sum=max(s[i],sum);
}
printf("%d\n",sum);
return 0;
}