【PAT甲级 - C++题解】1053 Path of Equal Weight

简介: 【PAT甲级 - C++题解】1053 Path of Equal Weight

1053 Path of Equal Weight


Given a non-empty tree with root R RR, and with weight W i W_iW

i

 assigned to each tree node T i T_iT

i

. The weight of a path from R RR to L LL is defined to be the sum of the weights of all the nodes along the path from R RR to any leaf node L LL.


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.


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hZ96rv96-1664980439849)(PAT 甲级辅导.assets/212)]

Input Specification:


Each input file contains one test case. Each case starts with a line containing 0<N NN≤100, the number of nodes in a tree, M MM (<N NN), the number of non-leaf nodes, and 0<S SS<230, the given weight number. The next line contains N NN positive numbers where W i W_iW

i

 (<1000) corresponds to the tree node T i T_iT

i

. Then M MM 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:



5.png

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


题意


给定一个值 S SS ,要求在树中从根结点到叶子结点的所有路径中找到路径权值之和等于 S SS 的路径。


假设给定数为 24 ,则存在 4 个具有相同给定权重的不同路径:{10 5 2 7},{10 4 10},{10 3 3 6 2},{10 3 3 6 2}, 已经在图中用红色标出。



a7484cedafe34d0fb7fba6c0d8a43beb.jpg




6.png

ID K ID[1] ID[2] ... ID[K]


ID 是一个两位数字,表示一个非叶子结点编号,K KK 是一个整数,表示它的子结点数,接下来的 K KK 个 ID[i] 也是两位数字,表示一个子结点的编号。


出于方便考虑,根节点固定为 00 ,且树中所有节点的编号为 00∼N−1 。


输出以单调递减的顺序输出所有权重为 S SS 的路径。


注意:这里单调递减指的是结果路径中按照字典序单调递减,比如 {4,1,5,3} 要比 {4,0,5,3} 和 {4,0,5,3,4} 都要大。


思路


利用邻接矩阵来存储每个结点之间的关系。

通过递归的方式寻找路径:

首先要判断当前结点是否为叶子结点。

如果是叶子结点则再判断当前路径之和是否等于 S SS ,如果等于则将当前路径加入答案数组 ans 中。

如果不是叶子结点则需要继续遍历其所有的孩子结点。

利用 sort 函数自带的排序性质即会自动按照字典序进行排序,只需要加一个 greater<vector<int>>() 的标志,表示以降序的方式排序。

输出最终结果,注意每行末尾不能有空格。



代码

#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int n, m, S;
int w[N];
bool g[N][N];
vector<vector<int>> ans;
void dfs(int u, int s, vector<int>& path)
{
    //判断当前结点是否为叶子结点
    bool is_leaf = true;
    for (int i = 0; i < n; i++)
        if (g[u][i])
        {
            is_leaf = false;
            break;
        }
    if (is_leaf) //如果是叶子结点
    {
        if (s == S)    ans.push_back(path);
    }
    else    //如果不是叶子结点
    {
        for (int i = 0; i < n; i++)
        {
            if (!g[u][i])    continue;
            path.push_back(w[i]);
            dfs(i, s + w[i], path);
            path.pop_back();
        }
    }
}
int main()
{
    cin >> n >> m >> S;
    for (int i = 0; i < n; i++)    cin >> w[i];  //输入每个结点的权值
    for (int i = 0; i < m; i++)    //输入所有结点的信息
    {
        int id, k;
        cin >> id >> k;
        while (k--)
        {
            int son;
            cin >> son;
            g[id][son] = true;
        }
    }
    vector<int> path = { w[0] };
    dfs(0, w[0], path);
    //sort会自动按照字典序的方式进行排序
    sort(ans.begin(), ans.end(), greater<vector<int>>());
    for (auto p : ans)
    {
        cout << p[0];
        for (int i = 1; i < p.size(); i++) cout << " " << p[i];
        cout << endl;
    }
    return 0;
}


目录
相关文章
|
7月前
|
编译器 程序员 API
【踩坑记录】解决GCC 中C++ 17 的 std::filesystem 链接报错:undefined reference to `std::filesystem::path
【踩坑记录】解决GCC 中C++ 17 的 std::filesystem 链接报错:undefined reference to `std::filesystem::path
2043 4
|
C++
【PAT甲级 - C++题解】1040 Longest Symmetric String
【PAT甲级 - C++题解】1040 Longest Symmetric String
68 0
|
算法 C++
【PAT甲级 - C++题解】1044 Shopping in Mars
【PAT甲级 - C++题解】1044 Shopping in Mars
88 0
|
C++
【PAT甲级 - C++题解】1117 Eddington Number
【PAT甲级 - C++题解】1117 Eddington Number
82 0
|
存储 C++ 容器
【PAT甲级 - C++题解】1057 Stack
【PAT甲级 - C++题解】1057 Stack
79 0
|
存储 C++
【PAT甲级 - C++题解】1055 The World‘s Richest
【PAT甲级 - C++题解】1055 The World‘s Richest
81 0
|
C++
【PAT甲级 - C++题解】1051 Pop Sequence
【PAT甲级 - C++题解】1051 Pop Sequence
85 0
|
人工智能 BI C++
【PAT甲级 - C++题解】1148 Werewolf - Simple Version
【PAT甲级 - C++题解】1148 Werewolf - Simple Version
140 0
|
29天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
50 2
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
103 5