题目
思路
题目大意:给一颗带有权值的树,找出并输出所有权值相加等于给定值的路径;
肯定是要用DFS做了,递归结束的条件可以这么分:
到达叶节点:如果到达叶节点,但是权值不等于给定值,则结束递归;如果权值和正好等于给定值,则输出路径;
未到达叶节点:若权值已经大于给定值,则直接结束递归;若权值不大于给定值,继续递归;
注意:根据id的实际意义,所以递归不能进行到叶子结点的下一层,需要提前判断是否到达叶节点;
在对一个节点进行DFS时,这个节点的权值还没有加入路径权值总和;
要求优先输出权值大的,那就在输入时把孩子节点由大到小排序
代码
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
#include <string>
#include <math.h>
using namespace std;
const int maxn = 105;
struct node{
vector<int> children;
}Node[maxn];
int weight[maxn], sum, n, m;
vector<int> tempPath;
inline bool cmp(int a, int b){
return weight[a] > weight[b];
}
void print(){
for(int i = 0; i < tempPath.size(); i ++){
printf("%d", weight[tempPath[i]]);
if(i != tempPath.size() - 1) printf(" ");
}
printf("\n");
}
void DFS(int id, int tempSum){
//找到有效路径
if(Node[id].children.size() == 0 && tempSum + weight[id] == sum){
tempPath.push_back(id);
print();
tempPath.pop_back();
}
//如果权重大于给定值或者遍历到叶子结点,都要结束递归
if(tempSum + weight[id] > sum || Node[id].children.size() == 0) return;
//如果不是叶子结点且节点总和小于给定值,继续递归
for(int i = 0; i < Node[id].children.size(); i ++){
tempPath.push_back(id);
DFS(Node[id].children[i], tempSum + weight[id]);
tempPath.pop_back();
}
return;
}
int main()
{
scanf("%d%d%d", &n, &m, &sum);
for(int i = 0; i < n; i ++) scanf("%d", &weight[i]);
int id, k, t;
//存储树
for(int i = 0; i < m; i ++){
scanf("%d%d", &id, &k);
for(int j = 0; j < k; j ++){
scanf("%d", &t);
Node[id].children.push_back(t);
}
//排序一下,保证节点id大的优先被选择
sort(Node[id].children.begin(), Node[id].children.end(), cmp);
}
DFS(0, 0);
system("pause");
return 0;
}