PAT(甲级)1053 Path of Equal Weight (30point(s))

题目

题目链接

思路

题目大意:给一颗带有权值的树,找出并输出所有权值相加等于给定值的路径;
肯定是要用DFS做了,递归结束的条件可以这么分:
到达叶节点:如果到达叶节点,但是权值不等于给定值,则结束递归;如果权值和正好等于给定值,则输出路径;
未到达叶节点:若权值已经大于给定值,则直接结束递归;若权值不大于给定值,继续递归;
注意:根据id的实际意义,所以递归不能进行到叶子结点的下一层,需要提前判断是否到达叶节点;
在对一个节点进行DFS时,这个节点的权值还没有加入路径权值总和;
要求优先输出权值大的,那就在输入时把孩子节点由大到小排序

代码
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
#include <string>
#include <math.h>
using namespace std;
const int maxn = 105;
struct node{
     vector<int> children;
}Node[maxn];

int weight[maxn], sum, n, m;
vector<int> tempPath;

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

void print(){
     for(int i = 0; i < tempPath.size(); i ++){
          printf("%d", weight[tempPath[i]]);
          if(i != tempPath.size() - 1) printf(" ");
     }
     printf("\n");
}
void DFS(int id, int tempSum){
     //找到有效路径
     if(Node[id].children.size() == 0 && tempSum + weight[id] == sum){
          tempPath.push_back(id);
          print();
          tempPath.pop_back();
     }
     //如果权重大于给定值或者遍历到叶子结点,都要结束递归
     if(tempSum + weight[id] > sum || Node[id].children.size() == 0) return;
     //如果不是叶子结点且节点总和小于给定值,继续递归
     for(int i = 0; i < Node[id].children.size(); i ++){
          tempPath.push_back(id);
          DFS(Node[id].children[i], tempSum + weight[id]);
          tempPath.pop_back();
     }
     return;
}
int main()
{
     scanf("%d%d%d", &n, &m, &sum);
     for(int i = 0; i < n; i ++) scanf("%d", &weight[i]);
     int id, k, t;
     //存储树
     for(int i = 0; i < m; i ++){
          scanf("%d%d", &id, &k);
          for(int j = 0; j < k; j ++){
               scanf("%d", &t);
               Node[id].children.push_back(t);
          }
          //排序一下,保证节点id大的优先被选择
          sort(Node[id].children.begin(), Node[id].children.end(), cmp);
     }
     DFS(0, 0);
     system("pause");
     return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值