1053 Path of Equal Weight——PAT甲级真题

1053 Path of Equal Weight

给定一个非空的树,树根为 RR。

树中每个节点 TiTi 的权重为 WiWi。

从 RR 到 LL 的路径权重定义为从根节点 RR 到任何叶节点 LL 的路径中包含的所有节点的权重之和。

现在给定一个加权树以及一个给定权重数字,请你找出树中所有的权重等于该数字的路径(必须从根节点到叶节点)。

例如,我们考虑下图的树,对于每个节点,上方的数字是节点 ID,它是两位数字,而下方的数字是该节点的权重。

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

212.jpg

输入格式

第一行包含三个整数 N,M,SN,M,S,分别表示树的总节点数量,非叶子节点数量,给定权重数字。

第二行包含 NN 个整数 WiWi,表示每个节点的权重。

接下来 MM 行,每行的格式为:

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

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

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

输出格式

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

每个路径占一行,从根节点到叶节点按顺序输出每个节点的权重。

注意:我们称 AA 序列 {A1,A2,…,An}{A1,A2,…,An} 大于 BB 序列 {B1,B2,…,Bm}{B1,B2,…,Bm},当且仅当存在一个整数 kk,1≤k<min(n,m)1≤k<min(n,m),对于所有 1≤i≤k1≤i≤k,Ai=BiAi=Bi 成立,并且 Ak+1>Bk+1Ak+1>Bk+1。

数据范围

1≤N≤1001≤N≤100,
0≤M<N0≤M<N,
0<S<2300<S<230,
0<Wi<10000<Wi<1000

输入样例:

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

输出样例:

10 5 2 7
10 4 10
10 3 3 6 2
10 3 3 6 2

题目大意:给你一棵树,让你从叶节点到根节点的权值之和等于S的路径。

大致思路:题目要求我们输出的时候要按照结点权值由大到小输出,所以在读入每个节点的孩子结点的时候,把每个结点的孩子结点按照权值的大小由大到小排序。同时我们还要定义一个path数组用来记录搜索路径。最后进行DFS。

代码:

#include <bits/stdc++.h>

using namespace std;

const int N = 110;
struct node {
    long long val;  //每个结点的权重
    vector<int> child;
    long long weight;  //记录每个结点的权重
} root[N];
long long n, m, s;
vector<int> path;
bool vis[N];  //标记当前结点有没有访问过
int cnt = 0;

void DFS(int x) {
    if (root[x].child.size() == 0) {
        if (root[x].weight == s) {
            // cout << "叶子结点为:" << x << endl;
            // cout << "结点权值是:" << root[x].weight << endl;
            for (int i = 0; i < path.size(); i++) {
                cout << root[path[i]].val;
                if (i != path.size() - 1)
                    cout << " ";
                else
                    cout << endl;
            }
            return;
        }
        return;
    }
    for (int i = 0; i < root[x].child.size(); i++) {
        int tmp = root[x].child[i];
        int w = root[tmp].weight;
        if (!vis[tmp]) {
            vis[tmp] = true;
            root[tmp].weight += root[x].weight;
            path.push_back(tmp);
            DFS(tmp);
            vis[tmp] = false;
            root[tmp].weight = w;  //回溯
            path.pop_back();
        }
    }
}

bool cmp(int a, int b) { return root[a].weight > root[b].weight; }

int main() {
    memset(vis, 0, sizeof(vis));
    cin >> n >> m >> s;
    for (int i = 0; i < n; i++) {
        scanf("%lld", &root[i].val);
        root[i].weight = root[i].val;
    }
    for (int i = 0; i < m; i++) {
        int id, k;
        cin >> id >> k;
        for (int j = 0; j < k; j++) {
            int x;
            cin >> x;
            root[id].child.push_back(x);
        }
        sort(root[id].child.begin(), root[id].child.end(), cmp);
    }
    path.push_back(0);
    DFS(0);
    return 0;
}

posted on 2021-02-10 22:11  翔鸽  阅读(87)  评论(0编辑  收藏  举报