欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

1053 Path of Equal Weight (30分)

程序员文章站 2022-07-07 18:57:23
...

1 题目

1053 Path of Equal Weight (30分)
Given a non-empty tree with root R, and with weight W​i
​​ assigned to each tree node T​i​​ . 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.

1053 Path of Equal Weight (30分)

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 W​i​​ (<1000) corresponds to the tree node T​i​​ . 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​​ ,B​2​​ ,⋯,B​m​ } if there exists 1≤k<min{n,m} such that A​i​​ =B​i for i=1,⋯,k, and A​k+1​​ >B​k+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])。
  • 3 注意事项

  • 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甲级