zoukankan      html  css  js  c++  java
  • 1053 Path of Equal Weight

    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.

    Input Specification:

    Each input file contains one test case. Each case starts with a line containing 0, the number of nodes in a tree, M (<), the number of non-leaf nodes, and 0, the given weight number. The next line contains N positive numbers where W​i​​ (<) 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 { is said to be greater than sequence { if there exists 1 such that A​i​​=B​i​​ for ,, 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

    题意:

      给出一棵树,每个节点既有编号又有权值,找出所有从根节点到叶子结点权值之和等于s的所有路径。

    思路:

      构造一个结构体,结构体中既有权重又有孩子结点,同时还有当前结点到达根节点的权重之和。其实寻找路径比较好找,我们用简单的DFS就能够把路径找到,但是问题要求输出的路径按照降序输出,看了别人的代码后,发现,在遍历孩子结点的时候如果我们能够保证孩子结点是由大到小的顺序,那么路径也就一定是由大到小的顺序。明白了只一点,这道题就简单了。

    Code:

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 struct Node {
     6     int val;
     7     vector<int> sons;
     8     int father = -1;
     9     int sum = 0;
    10 };
    11 
    12 vector<int> leaf;
    13 vector<Node> v;
    14 
    15 bool cmp(int a, int b) { return v[a].val > v[b].val; }
    16 
    17 void DFS(int index, int s) {
    18     if (v[index].father != -1) {
    19         int father = v[index].father;
    20         v[index].sum = v[father].sum + v[index].val;
    21     }
    22     if (v[index].sons.size() == 0) {
    23         if (v[index].sum == s) {
    24             vector<int> path;
    25             while (v[index].father != -1) {
    26                 path.push_back(v[index].val);
    27                 index = v[index].father;
    28             }
    29             path.push_back(v[index].val);
    30             reverse(path.begin(), path.end());
    31             for (int i = 0; i < path.size(); ++i) {
    32                 if (i == 0)
    33                     cout << path[i];
    34                 else
    35                     cout << " " << path[i];
    36             }
    37             cout << endl;
    38         }
    39         return;
    40     }
    41     for (int son : v[index].sons) DFS(son, s);
    42 }
    43 
    44 int main() {
    45     int n, m;
    46     long long s;
    47     cin >> n >> m >> s;
    48     v.resize(n);
    49     for (int i = 0; i < n; ++i) {
    50         cin >> v[i].val;
    51         v[i].sum = v[i].val;
    52     }
    53     for (int i = 0; i < m; ++i) {
    54         int index, k, son;
    55         cin >> index >> k;
    56         v[index].sum = v[index].val;
    57         for (int j = 0; j < k; ++j) {
    58             cin >> son;
    59             v[index].sons.push_back(son);
    60             v[son].father = index;
    61         }
    62         sort(v[index].sons.begin(), v[index].sons.end(), cmp);
    63     }
    64     DFS(0, s);
    65     return 0;
    66 }
    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    linux LTIB学习笔记
    wince WaitForMultipleObjects需要注意的问题
    微信小程序在苹果上出现[request:fail 发生了 SSL 错误无法建立与该服务器的安全连接。]错误的解决方案
    Windows 2008之PKI实战4:吊销
    十个不找工作的理由
    [zt]我奋斗了18年不是为了和你一起喝咖啡
    [zt]Java/PHP/C 几种语言 RSA 的互操作
    全职共享和兼职的一些思考pkill
    定价策略(翻译稿)
    Windows 2008之PKI实战1:管理
  • 原文地址:https://www.cnblogs.com/h-hkai/p/12846031.html
Copyright © 2011-2022 走看看