Cho cây không hướng n đỉnh (0 đến n-1), một số đỉnh có táo. Di chuyển qua một cạnh tốn 1 giây. Bắt đầu từ đỉnh 0, thu thập tất cả táo và quay lại 0. Tìm thời gian tối thiểu.
Ví dụ
Đầu vào: n=7, edges=[[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple=[f,f,t,f,t,t,f]
Đầu ra: 8.
Thuật toán DFS pós-order
Quan sát: một cạnh cần đi qua (2 lần: đi và về) nếu và chỉ nếu cây con phía dưới cạnh đó chứa ít nhất một táo.
- Xây dựng danh sách kề.
- DFS từ 0, tham số
parenttránh quay lại. - Hàm DFS trả về
truenếu cây con gốc tại node hiện tại có táo (bao gồm chính node). - Nếu con trả về true → cộng 2 vào kết quả (đi và về cạnh đó).
- Trả về
hasApple[node] || any_child_has_apple.
Triển khai C++
#include <bits/stdc++.h>
using namespace std;
class Solution {
int ans = 0;
bool dfs(int u, int p, const vector<bool>& apple, const vector<vector<int>>& g) {
bool has = apple[u];
for (int v : g[u]) if (v != p) {
if (dfs(v, u, apple, g)) {
ans += 2;
has = true;
}
}
return has;
}
public:
int minTime(int n, vector<vector<int>>& edges, vector<bool>& hasApple) {
vector<vector<int>> g(n);
for (auto& e : edges) {
g[e[0]].push_back(e[1]);
g[e[1]].push_back(e[0]);
}
dfs(0, -1, hasApple, g);
return ans;
}
};
Độ phức tạp
- Thời gian: O(N) - duyệt cây một lần.
- Không gian: O(N) - đồ thị và ngăn xếp đệ quy.
Kết quả kiểm thử
Đầu vào: 7, {{0,1},{0,2},{1,4},{1,5},{2,3},{2,6}}, {f,f,t,f,t,t,f}
Đầu ra: 8