Medium
Finish Time of Tasks I — C++
Full explanation · Time O(n) · Space O(n)
// Time: O(n)
// Space: O(n)
// iterative dfs, tree dp
class Solution {
public:
long long finishTime(int n, vector<vector<int>>& edges, vector<int>& baseTime) {
static const auto& POS_INF = numeric_limits<int64_t>::max();
static const auto& NEG_INF = numeric_limits<int64_t>::min();
vector<vector<int>> adj(n);
const auto iter_dfs = [&]() {
vector<int64_t> dp(n);
vector<pair<int, int>> stk = {{1, 0}};
while (!empty(stk)) {
const auto [step, u] = stk.back(); stk.pop_back();
if (step == 1) {
stk.emplace_back(2, u);
for (const auto& v : adj[u]) {
stk.emplace_back(1, v);
}
} else if (step == 2) {
auto mx = numeric_limits<int64_t>::min();
auto mn = numeric_limits<int64_t>::max();
for (const auto& v : adj[u]) {
mx = max(mx, dp[v]);
mn = min(mn, dp[v]);
}
dp[u] = (mx != NEG_INF ? (2 * mx - mn) : 0) + baseTime[u];
}
}
return dp[0];
};
for (const auto& e : edges) {
adj[e[0]].emplace_back(e[1]);
}
return iter_dfs();
}
};
// Time: O(n)
// Space: O(n)
// dfs, tree dp
class Solution2 {
public:
long long finishTime(int n, vector<vector<int>>& edges, vector<int>& baseTime) {
static const auto& POS_INF = numeric_limits<int64_t>::max();
static const auto& NEG_INF = numeric_limits<int64_t>::min();
vector<vector<int>> adj(n);
const auto dfs = [&](this auto&& dfs, int u) -> int64_t {
auto mx = NEG_INF, mn = POS_INF;
for (const auto& v : adj[u]) {
const auto& ret = dfs(v);
mx = max(mx, ret);
mn = min(mn, ret);
}
return (mx != NEG_INF ? (2 * mx - mn) : 0) + baseTime[u];
};
for (const auto& e : edges) {
adj[e[0]].emplace_back(e[1]);
}
return dfs(0);
}
};