PAT甲级 1053 等重路径

原题链接

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

树中每个节点 Ti 的权重为 Wi。

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

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

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

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

《PAT甲级 1053 等重路径》

 

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

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

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

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

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

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

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

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

数据范围
1≤N≤100,
0≤M<N,
0<S<230,
0<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

我的解法:

#include <bits/stdc++.h>
using namespace std;
const int N = 110;
bool g[N][N];
int w[N];
int n, m, S;
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]){
                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];
    }
    while(m --){
        int id, k;
        cin >> id >> k;
        while(k --){
            int kid;
            cin >> kid;
            g[id][kid] = true;
        }

    }
    vector <int> path({w[0]});
    dfs(0, w[0], path);
    sort(ans.begin(), ans.end(), greater<vector <int>>());
    for(int i = 0; i < ans.size(); i ++ ){
        cout << ans[i][0];
        for(int j = 1; j < ans[i].size(); j ++ ) cout << ' ' << ans[i][j];
        puts("");
    }
    // for(auto p : ans){
    //     cout << p[0];
    //     for(int i = 1; i < p.size(); i ++ ) cout << ' ' << p[i];
    //     puts("");
    // }
    return 0;
}

收获:

vector<vector<int>> 双重vector,sort比较按字典序排序序列

对于vector<vector<int>>,遍历使用auto,更方便

dfs还是写的太慢了,一定要捋清思路,找到结束条件

    原文作者:键盘奏鸣曲
    原文地址: https://blog.csdn.net/weixin_45660485/article/details/124917613
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞