dfs的应用,对于图结构的dfs遍历方法要熟悉
强烈推荐看灵神这题的题解,很精彩!
灵神的ac code:
自顶向下(递)
class Solution {
public:
double frogPosition(int n, vector<vector<int>> &edges, int t, int target) {
vector<vector<int>> g(n + 1);
g[1] = {0}; // 减少额外判断的小技巧
for (auto &e: edges) {
int x = e[0], y = e[1];
g[x].push_back(y);
g[y].push_back(x); // 建树
}
double ans = 0;
function<bool(int, int, int, long long)> dfs = [&](int x, int fa, int left_t, long long prod) -> bool {
// t 秒后必须在 target(恰好到达,或者 target 是叶子停在原地)
if (x == target && (left_t == 0 || g[x].size() == 1)) {
ans = 1.0 / prod;
return true;
}
if (x == target || left_t == 0) return false;
for (int y: g[x]) // 遍历 x 的儿子 y
if (y != fa && dfs(y, x, left_t - 1, prod * (g[x].size() - 1)))
return true; // 找到 target 就不再递归了
return false; // 未找到 target
};
dfs(1, 0, t, 1);
return ans;
}
};
作者:灵茶山艾府
链接:https://leetcode.cn/problems/frog-position-after-t-seconds/solutions/2281408/dfs-ji-yi-ci-you-qu-de-hack-by-endlessch-jtsr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
自底向上(归)
class Solution {
public:
double frogPosition(int n, vector<vector<int>> &edges, int t, int target) {
vector<vector<int>> g(n + 1);
g[1] = {0}; // 减少额外判断的小技巧
for (auto &e: edges) {
int x = e[0], y = e[1];
g[x].push_back(y);
g[y].push_back(x); // 建树
}
function<long long(int, int, int)> dfs = [&](int x, int fa, int left_t) -> long long {
// t 秒后必须在 target(恰好到达,或者 target 是叶子停在原地)
if (left_t == 0) return x == target;
if (x == target) return g[x].size() == 1;
for (int y: g[x]) { // 遍历 x 的儿子 y
if (y != fa) { // y 不能是父节点
auto prod = dfs(y, x, left_t - 1); // 寻找 target
if (prod) return prod * (g[x].size() - 1); // 乘上儿子个数,并直接返回
}
}
return 0; // 未找到 target
};
auto prod = dfs(1, 0, t);
return prod ? 1.0 / prod : 0;
}
};
作者:灵茶山艾府
链接:https://leetcode.cn/problems/frog-position-after-t-seconds/solutions/2281408/dfs-ji-yi-ci-you-qu-de-hack-by-endlessch-jtsr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。