-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path9_A1053.cpp
More file actions
146 lines (133 loc) · 3.74 KB
/
9_A1053.cpp
File metadata and controls
146 lines (133 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
* P305 Path of Equal Weights
*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Node
{
// 节点编号
int id;
// 节点权值
int weight;
// children,存数组下标
// 读入 children 的下标后,可以进行从大到小排序,权值更大的子结点优先访问
vector<int> children;
Node() {}
Node(int _weight): weight(_weight) {}
Node(int _id, int _weight): id(_id), weight(_weight) {}
};
// 树的节点数组
vector<Node> treeNodes;
// 比较函数,按权值从大到小排序
bool cmp(int a, int b)
{
return treeNodes[a].weight > treeNodes[b].weight;
}
// 访问 weightTotal
int init()
{
cout << "Input node amounts, non-leaf node amounts, and weight number: ";
int nodeNum, nonLeafNodeNum, weightTotal;
cin >> nodeNum >> nonLeafNodeNum >> weightTotal;
if (nonLeafNodeNum >= nodeNum)
{
cout << "non leaf node number is greater than total node number!" << endl;
return -1;
}
cout << "Input the weight of each node (from 00 ~ n): " << endl;
for (int i = 0; i < nodeNum; i++)
{
int weight;
cin >> weight;
Node newNode(i, weight);
treeNodes.push_back(newNode);
}
cout << "Input the non-leaf node's id, child amounts, and his child's id: " << endl;
for (int i = 0; i < nonLeafNodeNum; i++)
{
int nonLeafNodeId;
int childrenNum;
int childrenId;
cin >> nonLeafNodeId;
cin >> childrenNum;
for (int j = 0; j < childrenNum; j++)
{
cin >> childrenId;
treeNodes[nonLeafNodeId].children.push_back(childrenId);
}
// 读入 children 的下标后,可以进行从大到小排序,权值更大的子结点优先访问
sort(treeNodes[nonLeafNodeId].children.begin(), treeNodes[nonLeafNodeId].children.end(), cmp);
}
return weightTotal;
}
void testInit()
{
for (vector<Node>::iterator it = treeNodes.begin(); it != treeNodes.end(); it++)
{
printf("id: %02d, weight: %d \n", it->id, it->weight);
}
}
// print path
void print(vector<Node> &path)
{
for (vector<Node>::iterator it = path.begin(); it != path.end(); it++)
{
if (it == path.end() - 1)
{
cout << it-> weight << endl;
break;
}
cout << it-> weight << " ";
}
}
/**递归访问这个树
* index: 正在访问的这个节点的下标
* pathNodeNum: 当前路径上的节点数
* sum: 当前路径上的权值的总和
* weightTotal: 需要达到的权值和
*/
void DFS(int index, int pathNodeNum, int sum, int weightTotal, vector<Node> &path)
{
int currentSum = sum + treeNodes[index].weight;
// 加上这个节点后,权值大于目标值,return
if ( currentSum > weightTotal)
{
return;
}
else if (currentSum == weightTotal)
{
// 如果是叶子节点,将该节点加入path,输出路径
if (treeNodes[index].children.empty())
{
path.push_back(treeNodes[index]);
print(path);
path.pop_back();
}
// 如果不是叶子节点,return
else
{
return;
}
}
else if (currentSum < weightTotal)
{
// 将自己加入 path 中,然后递归访问每个子结点
path.push_back(treeNodes[index]);
for (int i = 0; i < treeNodes[index].children.size(); i++)
{
DFS(treeNodes[index].children[i], path.size(), currentSum, weightTotal, path);
}
// 结束后,将自己从 path 中弹出
path.pop_back();
}
}
int main()
{
int weightTotal = init();
// testInit();
vector<Node> path;
DFS(0, 0, 0, weightTotal, path);
return 0;
}