题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805424153280512
题目给出树的结构和权重信息,要求从根节点出发到达叶节点的权重和等于给定的目标值,并且将路径从大到小排序输出。
首先根据树的结构将树构建出来,然后考虑到最后需要将路径从大到小输出,所以保存路径的时候直接对孩子节点进行从大到小排序,这样找到符合的路径可以直接输出。然后深度遍历,path保存的是节点的编号信息,权重信息在树中保存,当遍历到根节点而且正好权值和等于目标值,输出路径。代码如下:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int target; //目标值
struct node{ //树的节点
int w; //权重
vector<int> child;
};
vector<node> tree; //树
vector<int> path; //保存着等于目标值得路径
bool cmp(int a,int b){ //将孩子直接按大到小排序,即可直接输出
return tree[a].w > tree[b].w;
}
void dfs(int index, int nodenum, int sum){ //深度优先遍历整个树
if(sum > target) return; //大于目标值,直接返回
if(sum == target){ //等于目标值时
if(tree[index].child.size() != 0) return; //还有孩子节点,不是要找到路径,直接返回
for(int i = 0; i < nodenum; i++){ //否则,将路径上的权重输出
if(i != nodenum-1)
cout << tree[path[i]].w << " ";
else
cout << tree[path[i]].w << endl;
}
return;
}
for(int i = 0; i < tree[index].child.size(); i++){ //遍历当前节点的孩子节点进行搜索,并保存当前搜索的路径
int nod = tree[index].child[i];
path[nodenum] = nod;
dfs(nod,nodenum+1,sum+tree[nod].w);
}
}
int main(){
int n,m,x,k,stem;
cin >> n >> m >> target;
tree.resize(n); //设置树的节点
path.resize(n); //路径上最多n个节点
for(int i = 0; i < n ; i++){
cin >> tree[i].w; //输入权重
}
for(int i = 0; i < m; i++){
cin >> x >> k; //输入非叶节点
tree[x].child.resize(k);
for(int j = 0; j < k; j++){
cin >> tree[x].child[j]; //输入孩子节点
}
sort(tree[x].child.begin(),tree[x].child.end(),cmp); //对孩子节点进行排序
}
dfs(0,1,tree[0].w); //从根节点深度优先遍历
return 0;
}