版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26398495/article/details/81812157
题目链接
题目分析
给出特定值S
,查找(根结点到所有叶结点的权重和 = S
) 的所有路径
1、根节点编号:0
2、输出:满足条件的weight
序列,降序,
解题思路
1、建树(静态存储);
2、先根遍历,用vector<int>
保存路径 (注意递归返回时弹出加入的那个结点);
3、vector[]
数组保存多个结果,vector
可以直接比较,用sort()
函数排序;
AC程序(C++)
/**************************
*@Author: 3stone
*@ACM: PAT.A1053 Path of Equal Weight
*@Time: 18/7/30
*@IDE: VSCode 2018 + clang++
***************************/
#include<cstdio>
#include<vector>
#include<algorithm>
#define maxn 110
using namespace std;
int weight[maxn]; //记录所有结点权重
int n, m, s;
vector<int> result[maxn]; //记录所有满足条件的路径(上限:叶节点个数)
int result_num; //路径数
//树结点
struct Node {
int weight;
int child_num;
vector<int> child; //子节点指针
}node[maxn];
//比较函数(vector可以直接比较)
bool cmp_vector(vector<int> a, vector<int> b) {
if(a > b) return true;
else return false;
}
//先序遍历
void pre_order(int root, vector<int> rt, int cur_sum) {
rt.push_back(node[root].weight); //记录weight
cur_sum += node[root].weight; //累加 weight
if(node[root].child.size() == 0){ //叶节点
if (cur_sum == s) { //满足条件
result[result_num++] = rt;
}
rt.pop_back(); //弹出,退回上一层
return;
}
//非叶节点,但权重和已越界
if(cur_sum >= s){
rt.pop_back();
return;
}
//非叶节点, 且权重 < S
for(int i = 0; i < node[root].child.size(); i++){
pre_order(node[root].child[i], rt, cur_sum);
}
rt.pop_back(); //弹出,退回上一层
}
int main() {
int k, child_num, temp;
while(scanf("%d %d %d", &n, &m, &s) != EOF) {
//初始化 结点信息
for(int i = 0; i < maxn; i++) {
node[i].child.clear();
}
result_num = 0; //满足条件的路径数
//输入结点权重
for(int i = 0; i < n; i++) {
scanf("%d", &node[i].weight);
}
//输入并保存结点关系
for(int i = 0; i < m; i++) { //非叶结点
scanf("%d %d", &k, &child_num);
for(int j = 0; j < child_num; j++) {
scanf("%d", &temp);
node[k].child.push_back(temp);
}
}
vector<int> rt;
//先根遍历 查找满足条件的路径
pre_order(0, rt, 0);
sort(result, result + result_num);
for(int i = result_num - 1; i >= 0; i--) {
for(int j = 0; j < result[i].size() - 1; j++)
printf("%d ", result[i][j]);
printf("%d\n", result[i][result[i].size() - 1]);
}
}//while-scanf
return 0;
}