首先,如果出现了这样的情况,大概率,代码逻辑是:在输入完每个非叶结点的孩子之后,将该结点的孩子结点按照权值排序,然后,代码去dfs遍历的时候,确实是首先遍历到权值大的孩子,然后保存路径、判断、输出路径。
这逻辑没错,但是有漏洞。
具体情况参考这篇文章
看完这篇文章里面的例子,就明白了。
这种判断逻辑,这能保证在同一层结点选择时,首先选择权值最大的结点,而如果在同一层有两个权值相同的结点,而下一层上,这两个结点的孩子权值不同,可能就会出错。
AC代码
代码逻辑是,直接找到所有符合条件的路径,然后对路径进行排序、输出。
#include <bits/stdc++.h>
using namespace std;
int n, m, s;
int w[100];
vector<int> tree[100];
vector<int> temp;
vector<vector<int>> ans; // 存放所有路径
void show(vector<int> &ans) {
for (int i = 0; i < ans.size(); i++) {
if (i) printf(" ");
printf("%d", ans[i]);
}
printf("\n");
}
void dfs(int root, int cur_sum) {
if (cur_sum > s) return;
if (tree[root].size() == 0) {
if (cur_sum + w[root] == s) {
temp.push_back(w[root]);
ans.push_back(temp);
temp.pop_back();
}
return;
}
temp.push_back(w[root]);
for (int i = 0; i < tree[root].size(); i++) {
dfs(tree[root][i], cur_sum + w[root]);
}
temp.pop_back();
}
int main()
{
scanf("%d%d%d", &n, &m, &s);
for (int i = 0;i < n; i++) scanf("%d", w + i);
for (int i = 0;i < m; i++) {
int id, k;
scanf("%d%d", &id, &k);
while (k--) {
int kid;
scanf("%d", &kid);
tree[id].push_back(kid);
}
}
dfs(0, 0); // 将要处理的结点编号、在到达当前结点的之前的路径权重之和
sort(ans.begin(), ans.end(), greater<vector<int>>() );
// 这个排序方法,值得学习,对每个vector<int>,也可以像常规数据类型一样的排序,要加()
for (int i = 0; i < ans.size(); i++) {
show(ans[i]);
}
return 0;
}