【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;
}


目录
相关文章
|
6月前
|
编译器 程序员 API
【踩坑记录】解决GCC 中C++ 17 的 std::filesystem 链接报错:undefined reference to `std::filesystem::path
【踩坑记录】解决GCC 中C++ 17 的 std::filesystem 链接报错:undefined reference to `std::filesystem::path
1836 4
|
C++
【PAT甲级 - C++题解】1040 Longest Symmetric String
【PAT甲级 - C++题解】1040 Longest Symmetric String
66 0
|
算法 C++
【PAT甲级 - C++题解】1044 Shopping in Mars
【PAT甲级 - C++题解】1044 Shopping in Mars
82 0
|
C++
【PAT甲级 - C++题解】1117 Eddington Number
【PAT甲级 - C++题解】1117 Eddington Number
76 0
|
存储 C++ 容器
【PAT甲级 - C++题解】1057 Stack
【PAT甲级 - C++题解】1057 Stack
76 0
|
存储 C++
【PAT甲级 - C++题解】1055 The World‘s Richest
【PAT甲级 - C++题解】1055 The World‘s Richest
78 0
|
C++
【PAT甲级 - C++题解】1051 Pop Sequence
【PAT甲级 - C++题解】1051 Pop Sequence
79 0
|
人工智能 BI C++
【PAT甲级 - C++题解】1148 Werewolf - Simple Version
【PAT甲级 - C++题解】1148 Werewolf - Simple Version
134 0
|
7天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
34 4
|
9天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
31 4