同样思路使用两种不同的编码实现。
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct Node{
int weight;
vector<int> child;
};
Node t[1010];
vector<vector<int> > serialStore;
vector<int> tmpSerial;
bool cmp(vector<int> a, vector<int> b){
if(a.empty() || b.empty()){
return a.empty();
}
int minL = min(a.size(), b.size());
for(int i = 0; i < minL; i++){
if(a[i] != b[i]) return a[i] > b[i]; // 关键在这里的大于号
}
return false;
}
// 测试cmp是否工作的函数
void sortSerial(){
vector<int> tmp;
tmp.push_back(10);tmp.push_back(3);tmp.push_back(3);tmp.push_back(6);tmp.push_back(2);
serialStore.push_back(tmp);
tmp.clear();
tmp.push_back(10);tmp.push_back(5);tmp.push_back(2);tmp.push_back(7);
serialStore.push_back(tmp);
tmp.clear();
tmp.push_back(10);tmp.push_back(4);tmp.push_back(10);
serialStore.push_back(tmp);
tmp.clear();
tmp.push_back(10);tmp.push_back(3);tmp.push_back(3);tmp.push_back(6);tmp.push_back(2);
serialStore.push_back(tmp);
tmp.clear();
sort(serialStore.begin(), serialStore.begin() + 4, cmp);
while(!serialStore.empty()){
vector<int> v = serialStore.front();
while(!v.empty()){
printf("%d ", v.front());
v.erase(v.begin(), v.begin() + 1);
}
serialStore.erase(serialStore.begin(), serialStore.begin() + 1);
printf("\n");
}
}
int N, M, S;
// N: 节点个数, M: 非叶节点个数, S: 给定权值
void printLayer(int num){
printf("%02d", num); // 不足两位,以0补齐
}
void preOrder(int root){
// printLayer(root);
// printf(" %d %d\n", t[root].weight, nowLayer);
// 访问节点的逻辑应该就是:将节点的权值加入临时序列存储
tmpSerial.push_back(t[root].weight);
if(!t[root].child.empty()){
for(int i = 0; i < t[root].child.size(); i++){
preOrder(t[root].child[i]);
}
} else{ // 叶子节点的逻辑
// 到达叶子节点之后 先计算加和
int sum = 0;
for(int i = 0; i < tmpSerial.size(); i++){
sum += tmpSerial[i];
}
if(sum == S){
serialStore.push_back(tmpSerial);
}
}
tmpSerial.pop_back();
}
int main(){
scanf("%d %d %d", &N, &M, &S);
for(int i = 0; i < N; i++){
scanf("%d", &(t[i].weight));
}
int nodeIdx, childNum;
int tmpWeight;
while(scanf("%d %d", &nodeIdx, &childNum) != EOF){
while(childNum --){
scanf("%d", &tmpWeight);
t[nodeIdx].child.push_back(tmpWeight);
}
}
// 尝试先根遍历整棵树
preOrder(0);
// sortSerial();
if(serialStore.size() > 1)
sort(serialStore.begin(), serialStore.begin() + serialStore.size(), cmp);
while(!serialStore.empty()){
vector<int> v = serialStore.front();
while(!v.empty()){
printf("%d", v.front());
v.erase(v.begin());
if(!v.empty())
printf(" ");
}
serialStore.erase(serialStore.begin());
if(!serialStore.empty())
printf("\n");
}
return 0;
}
另一种方法
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
// 建立树的节点
struct node{
int weight = -1;
vector<int> child;
}tree[110]; // 节点最大个数
int N = -1, M = -1, S = -1;
vector<vector<int> > solve; // 结果集合是一个二维数组
vector<int> now_trace;
bool cmp(vector<int> a, vector<int> b){
int len = min(a.size(), b.size());
// 先遍历都有的
for(int i = 0; i < len; i++){
if(a[i] != b[i]){
return a[i] > b[i];
}
}
// 如果循环完了还不return 那谁长谁大
return a.size() > b.size();
}
// sum 是上层传上来的
void DFS(int idx, int sum){
// 访问根节点
int this_weight = tree[idx].weight;
sum += this_weight;
now_trace.push_back(this_weight);
if(sum < S){
// 循环遍历子节点
for(int i = 0; i < tree[idx].child.size(); i++){
DFS(tree[idx].child[i], sum);
}
} else if(sum == S){
if(tree[idx].child.empty()) {// 如果是叶子节点则符合要求
solve.push_back(now_trace);
}
}
now_trace.pop_back();
}
int main(){
// 扫描节点个数,叶子节点个数 ,给定权值
scanf("%d %d %d", &N, &M, &S);
// 扫描权值数组
for(int i = 0; i < N; i ++){
scanf("%d", &(tree[i].weight));
}
// 扫描每个节点
// 新建节点不使用p306 newNode 因为这里很多东西都是给定好的
for(int i = 0; i < M; i ++){ // 直接遍历非叶节点
int idx = -1;
scanf("%d", &idx);
int child_num = -1;
scanf("%d", &child_num);
while(child_num --){
int child_idx = -1;
scanf("%d", &child_idx);
tree[idx].child.push_back(child_idx);
}
}
// 测试一下结构
// for(int i = 0; i < N; i++){
// printf("%0d %0d ", i, tree[i].child.size());
// for(int j = 0; j < tree[i].child.size(); j++){
// printf("%d ", tree[i].child[j]);
// }
// printf("\n");
// }
// 测试一下层序遍历
// queue<int> q;
// q.push(0);
// while(!q.empty()){
// int front = q.front();
// q.pop();
// printf("%d ", tree[front].weight);
// for(int i = 0; i < tree[front].child.size(); i++){
// q.push(tree[front].child[i]);
// }
// }
// 成功扫描进来了,之后就是按要求进行先根遍历并记录序列
DFS(0, 0);
// 测试之后能成功遍历 下面面临排序
sort(solve.begin(), solve.end(), cmp);
for(int i = 0; i < solve.size(); i++){
for(int j = 0; j < solve[i].size(); j++ ){
printf("%d", solve[i][j]);
if(j != solve[i].size() - 1){
printf(" ");
}
}
if(i != solve.size() - 1){
printf("\n");
}
}
return 0;
}
附AC结果