题目传送门<==戳这
一道树的遍历
1.树的每一个结点储存:结点的权值,结点的儿子(vector数组动态存储)
2.对于每一个结点的儿子结点数组,要对他们进行不升序排列,这样就能够优先选择儿子结点中权值较大的那个元素
3.因为最后要输出总和为s的各个结点的权值,因此用path数组记录经过的结点的下标。
上代码理解:
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=105;
int n,m,s;
int path[maxn];
struct node{
int weight; //权值vector<int> child; //储存子结点的 “ 下标 ”
}a[maxn];
void dfs(int id,int num,int ans){
//当前结点的下标 id ,当前处理完 num-1 个结点,当前处理完的结点的权值和 ansif(ans>s) return;else if(ans==s){
if(a[id].child.size()==0){
//如果是叶子结点cout<<a[path[1]].weight;for(int i=2;i<=num-1;i++){
cout<<" "<<a[path[i]].weight;}putchar('\n');}}else if(ans<s){
for(int i=0;i<a[id].child.size();i++){
//枚举下标为 id 的结点的子结点int child=a[id].child[i];path[num]=child;dfs(child,num+1,ans+a[child].weight);}}
}
bool cmp(int f,int g){
//不升序排列return a[f].weight>a[g].weight;
}
int main(){
cin>>n>>m>>s;for(int i=0;i<n;i++){
cin>>a[i].weight;}int id,k,temp;for(int i=1;i<=m;i++){
cin>>id>>k;for(int j=1;j<=k;j++){
cin>>temp; a[id].child.push_back(temp);}sort(a[id].child.begin(),a[id].child.end(),cmp);}path[1]=0; //初始化,路线的第一个结点的下标默认为 0dfs(0,2,a[0].weight); //搜索
}