//二叉树,如果题目里给的是边那么往往是图的问题
struct node{
int data;
node* lchild;
node* rchild;
}
node* root = NULL; //二叉树建树前根节点不存在
node* newNode(int v){
node* Node = new node;
Node->data = v;
Node->lchild = Node->rchild =NULL;
return Node;
}
void search(node* root,int x,int newdata) //二叉树节点的查找、修改
{
if(root == NULL){
return;
}
if(root->data == x){
root ->data = newdata;
}
search(root->lchild,x,newdata);
search(root->rchild,x,newdata);
}
void insert(node* &root,int x) //关键一点是根节点指针root用了引用&,在函数
{ //里修改root会直接修改原变量,insert()必须加引用
if(root == NULL){
root = newNode(x);
return;
}
if(由二叉树的性质,x插在左子树){
insert(root->lchild,x);
}
else{
insert(root->rchild,x);
}
}
node* Create(int data[],int n)
{
node* root = NULL;
for(int i=0;i<n;i++)
insert(root,data[i]);
return root;
}
void preorder(node* root){
if(root == NULL)
return; //到达空树,递归边界
printf("%d\n",root->data); //举例,比如输出这个点的值,可以为char等等任意类型
preorder(root->lchild);
preorder(root->rchild);
}
//树的遍历
struct node{
int data;
int child[N]; //指针域,用于存放所有子节点的下标
}Node[N];
int idx;
int newNode(int v)
{
Node[idx].data = v;
Node[idx].child.clear(); //清空子结点
return idx++; //返回结点下标,并令idx自增
}
//在考试中涉及非二叉树的树的考察是,
//一般都给出结点的编号,并且编号是0,1,2这种给法
//这种情况下就不需要使用newNode函数了
//树的先根遍历
void preorder(int root)
{
cout<<Node[root].data;
for(int i=0;i<Node[root].child.size();i++)
preorder(Node[root].child[i]);
}
//https://blog.csdn.net/weixin_39485901/article/details/89236862 数组用法
//树的层序遍历
void LayerOrder(int root){
queue<int> Q;
Q.push(root);
while(!Q.empty())
{
int front = Q.front();
cout<<Node[front].data;
Q.pop();
for(int i =0 ;i < Node[front].child.size();i++)
Q.push(Node[front].child[i]);
}
}
/*P307
给定一棵树和每个结点的权值,求所有从根节点到叶子节点的路径,使得每条路径上的结点
的权值纸盒等于给定的常数S。如果有多条这样的路径,则按路径非递增的顺序输出。
令结构体node存放结点的数据域和指针域,其中指针域使用vector存放所有孩子结点的编号。
权值从大到小排序,读入的时候就把vector的结点从大到小,就能优先遍历大。
递归过程伪代码:
若sum > s,直接return
若sum = s,输出path[]
若sum < s,枚举所有当前访问结点idx的所有子结点,对每一个子节点child,先将其存入path[numNode],
然后利用递归参数child , numNode + 1 , sum + node[child].weight 往下一层递归 。 */
#include<bits/stdc++.h>
using namespace std;
const int N =110;
struct node{
int weight;
vector<int> child; //vector<int> child储存结点的代号,和idx存储的是一个东西
}Node[N]; //为什么?因为考试里的题往往都给了下标,不是idx++那个方向
bool cmp(int a,int b){
return Node[a].weight>Node[b].weight;
}
int n,m,s;
int path[N];
void DFS(int idx,int numNode,int sum){
if(sum > s) return;
if(sum == s){
if(Node[idx].child.size()!=0) return;
for(int i = 0;i<numNode;i++){
printf("%d",Node[path[i]].weight);
if(i < numNode - 1) printf(" ");
else printf("\n");
}
return;
}
for(int i=0;i < Node[idx].child.size();i++){
int child = Node[idx].child[i];
path[numNode] = child;
DFS(child , numNode + 1 , sum + Node[child].weight );
}
}
//这个题处理输入也有点麻烦
int main(){
scanf("%d%d%d".&n,&m,&S);
for(int i=0;i<n;i++){
scanf("%d%d",&id,&k);
for(int j =0;j<k;j++){
scanf("%d",&child);
Node[id].child.push_back(child);
}
sort(Node[id].child.begin(),Node[id].child.end(),cmp);
}
path[0] = 0;
DFS(0,1,Node[0].weight);
return 0;
}