题目描述:
给定一个整数 n n n表示有 0 , 1 , 2 , 3 , . . . , n − 1 0, 1, 2, 3, ..., n-1 0,1,2,3,...,n−1共 n n n个任务同时给定一个数组 c o s t T i m e costTime costTime, c o s t T i m e [ i ] costTime[i] costTime[i]表示第 i i i个任务执行所需要的时间。给定 m m m条依赖关系,每条依赖关系由两个整数 u , v u, v u,v描述,表示任务 u u u开始之前任务 v v v必须完成。输出每个任务的最早完成时间(初始时间为 0 0 0时刻)。输入保证每个任务最终均能完成。
题解:
拓扑排序的模板题,只需要将依赖关系看成有向图的边,边的长度成为上一个任务执行所需要的时间;而一个任务的开始时间为其依赖任务的最晚完成时间,只需要取最大值即可,开始时间加上自身任务需要的时间就是该任务的最早完成时间。
代码:
#include <bits/stdc++.h>
const int MAXN = 1e5 + 10;
using namespace std;
int n, m;
int inDegree[MAXN], costTime[MAXN], ans[MAXN];
vector<int> g[MAXN];
void topoSort()
{
queue<int> q;
for (int i = 0; i < n; i++) {
if (inDegree[i] == 0) {
q.push(i);
ans[i] = costTime[i];
}
}
while(!q.empty()) {
int u = q.front();
q.pop();
for (auto v : g[u]) {
ans[v] = max(ans[v], ans[u]); // v的开始时间应该是其依赖的任务的最晚完成时间,所以此处取最大值
inDegree[v]--;
if (inDegree[v] == 0) {
ans[v] += costTime[v]; // 开始时间加上自己所需要的时间就是完成时间
q.push(v);
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 0; i < n; i++) { cin >> costTime[i]; }
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v; // u开始之前v必须完成则建立v->u的单向边
g[v].push_back(u);
inDegree[u]++;
}
topoSort();
for (int i = 0; i < n; i++) { cout << ans[i] << (i == n-1 ? "\n" : " "); }
return 0;
}