1053 Path of Equal Weight (30分)
1 题目
1053 Path of Equal Weight (30分)
Given a non-empty tree with root R, and with weight Wi
assigned to each tree node Ti . The weight of a path from R to L is defined to be the sum of the weights of all the nodes along the path from R to any leaf node L.
Now given any weighted tree, you are supposed to find all the paths with their weights equal to a given number. For example, let’s consider the tree showed in the following figure: for each node, the upper number is the node ID which is a two-digit number, and the lower number is the weight of that node. Suppose that the given number is 24, then there exists 4 different paths which have the same given weight: {10 5 2 7}, {10 4 10}, {10 3 3 6 2} and {10 3 3 6 2}, which correspond to the red edges in the figure.
Input Specification:
Each input file contains one test case. Each case starts with a line containing 0<N≤100, the number of nodes in a tree, M (<N), the number of non-leaf nodes, and 0<S<2^30, the given weight number. The next line contains N positive numbers where Wi (<1000) corresponds to the tree node Ti . Then M lines follow, each in the format:
ID K ID[1] ID[2] … ID[K]
where ID is a two-digit number representing a given non-leaf node, K is the number of its children, followed by a sequence of two-digit ID’s of its children. For the sake of simplicity, let us fix the root ID to be 00.
Output Specification:
For each test case, print all the paths with weight S in non-increasing order. Each path occupies a line with printed weights from the root to the leaf in order. All the numbers must be separated by a space with no extra space at the end of the line.
Note: sequence {A1 ,A2,⋯,An } is said to be greater than sequence {B1 ,B2 ,⋯,Bm } if there exists 1≤k<min{n,m} such that Ai =Bi for i=1,⋯,k, and Ak+1 >Bk+1.
Sample Input:
20 9 24
10 2 4 3 5 10 2 18 9 7 2 2 1 3 12 1 8 6 2 2
00 4 01 02 03 04
02 1 05
04 2 06 07
03 3 11 12 13
06 1 09
07 2 08 10
16 1 15
13 3 14 16 17
17 2 18 19
Sample Output:
10 5 2 7
10 4 10
10 3 3 6 2
10 3 3 6 2
2 解析
2.1 题意
给定一棵树和结点权值,求这颗树所有从根结点到叶子结点的路径权值之和等于S的路径,并按路径非递增的顺序输出。
2.2 思路
- 1,用树的静态写法创建二叉树
- 结构体中:vector存放该结点所有孩子的编号,int类型变量存放权值
- 为了 满足最后的权值从大到小排序输出, 在输入时,就把vector按vector的权值从大到小排序
- 2, 求路径就相当于对树进行先根遍历(DFS遍历),
- 参数:
- index:当前访问结点编号
- numNode:当前路径path上的结点个数
- weightSum:当前路径的权值和
- 递归过程:
- 1, weightSum > S时,直接return
- 2, weightSum =S 时,若结点index为叶子结点时,return;否则,输出path数组中的所有数据
- 3,若Sum< S时,说明还未满足条件。枚举当前index的所有子结点,对每个子结点child,将其存入path[numNode]中,然后在此基础上,进行下一层递归(child, numNode + 1, sum + Node[child.weight])。
- 参数:
- weightSum等于S时,必须判断该结点是叶子结点才输出,因为题目要求的是根结点到叶子结点的路径。
- cmp的所有情况都必须要有返回值,程序需要处理两条路径上结点权值完全相同的情况。
3 参考代码
- 方法一:
#include <cstdio>
#include <algorithm>
using std::sort;
int N, M, S;
const int MAXN = 110;
int path[MAXN];
struct node
{
vector<int> child;
int weight;
}Node[MAXN];
bool cmp(int a, int b){
return Node[a].weight > Node[b].weight;
}
//index:当前访问的结点,numNode:当前路径path上的结点个数,weightSum:当前结点结点权值和
void DFS(int index, int numNode, int weightSum){
if(weightSum > S) return;
if(weightSum == S){
//还没有到叶子结点返回
if(Node[index].child.size() != 0) return;
//到达叶子结点,path[]中存放了一个完整的路径,输出它
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[index].child.size(); ++i)
{
int child = Node[index].child[i]; //结点index的第i个子结点编号
path[numNode] = child; //将结点child加入path末尾
DFS(child, numNode + 1, weightSum + Node[child].weight); //递归进入下一层
}
}
int main(int argc, char const *argv[])
{
scanf("%d%d%d", &N, &M, &S);
for (int i = 0; i < N; ++i)
{
scanf("%d", &Node[i].weight);
}
int ad, k;
for (int i = 0; i < M; ++i)
{
scanf("%d%d", &ad, &k);
int temp;
for (int j = 0; j < k; ++j)
{
scanf("%d", &temp);
Node[ad].child.push_back(temp);
}
sort(Node[ad].child.begin(), Node[ad].child.end(), cmp);
}
path[0] = 0;//路径第一个结点为零号结点
DFS(0, 1, Node[0].weight);
return 0;
}
- 方法二:
用vector代替path数组
#include <cstdio>
#include <vector>
#include <algorithm>
using std::vector;
using std::sort;
int N, M, S;
const int MAXN = 110;
vector<int> path;
struct node
{
vector<int> child;
int weight;
}Node[MAXN];
bool cmp(int a, int b){
return Node[a].weight > Node[b].weight;
}
//index:当前访问的结点,numNode:当前路径path上的结点个数,weightSum:当前结点结点权值和
void DFS(int index, int weightSum){
if(weightSum > S) return;
if(weightSum == S){
//还没有到叶子结点返回
if(Node[index].child.size() != 0) return;
//到达叶子结点,path[]中存放了一个完整的路径,输出它
for (int i = 0; i < path.size(); ++i)
{
printf("%d", Node[path[i]].weight);
if(i < path.size() - 1){
printf(" ");
}else{
printf("\n");
}
}
return;
}
for (int i = 0; i < Node[index].child.size(); ++i)
{
int child = Node[index].child[i]; //结点index的第i个子结点编号
path.push_back(child);
DFS(child, weightSum + Node[child].weight); //递归进入下一层
path.pop_back();
}
}
int main(int argc, char const *argv[])
{
scanf("%d%d%d", &N, &M, &S);
for (int i = 0; i < N; ++i)
{
scanf("%d", &Node[i].weight);
}
int ad, k;
for (int i = 0; i < M; ++i)
{
scanf("%d%d", &ad, &k);
int temp;
for (int j = 0; j < k; ++j)
{
scanf("%d", &temp);
Node[ad].child.push_back(temp);
}
sort(Node[ad].child.begin(), Node[ad].child.end(), cmp);
}
path.push_back(0);//路径第一个结点为零号结点
DFS(0, Node[0].weight);
return 0;
}
推荐阅读
-
PAT A1053:Path of Equal Weight
-
(pat)A1053 Path of Equal Weight
-
PAT A1053 Path of Equal Weight(30 分)
-
PAT A1053 Path of Equal Weight (30分)
-
PAT甲级——A1053 Path of Equal Weight【30】
-
PAT甲级——A1053 Path of Equal Weight
-
1053 Path of Equal Weight (30 分)
-
1053 Path of Equal Weight (30 分)
-
1053 Path of Equal Weight (30 分)
-
1053 Path of Equal Weight (30分)