PAT A1053 Path of Equal Weight

一、题目详情

输入解释

  • 第一行给出三个数字N、M、S,分别为树的结点数量、树的非叶节点数量、给定的权重
  • 第二行给出N个数字,分别是编号1~N的结点的权重
  • 接下来M行依次为:非叶节点的编号 该结点的子结点个数 子结点的编号

输出解释

每行输出一个路径(以结点的权重表示),使得路径上的结点权重相加之和等于给定的权重

思路

  1. 首先是确定数据结构,考虑静态实现,邻接表可以用vector<int> child来实现。每个结点都有一个权重,所以考虑用结构体node来表示结点。node中有一个int weight和vector<int> child。nodes[maxn]为结构体数组。
  2. 可以想到是用DFS来做,需要传递的参数有:当前路径上的结点个数num(如果是用数组来表示路径的话,必须要有结点个数,不然给数组中的哪个元素赋值呢)、当前的边权之和w、当前正在处理的结点index(有了这个才能通过child数组找到孩子哇)、保存路径的数组path[]设置为全局变量(不知道为什么,DFS都是这样做的)
  3. 递归式:DFS(nodes[index].child[i],num+1,w+nodes[nodes[index].child[i]].weight)
  4. 递归边界:有两个需要注意的条件 ①sum和S的大小关系(sum小于S时,继续递归,sum大于S时,没有可行的解,回溯) ②题目要求路径必须是从根节点到叶节点,因此要判断是否为叶节点,在这个题中就是在sum等于S时判断nodes[index].child.size()是否为0。
  5. 题目要求在有多条路径时,要先输出结点权重大的,可以对child进行排序,这样dfs时就是按权重从大到小进行的。

二、实现代码

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 111;
int N,M,S;

int path[maxn];
struct node
{
    int weight;
    vector <int> child;
}nodes[maxn];
bool cmp(int a,int b)
{
    return nodes[a].weight>nodes[b].weight;
}
void DFS(int index,int num,int sum)
{
    if(sum>S) return;
    else if(sum==S){
        if(nodes[index].child.size()==0)
        {
            for(int i=0;i<num;i++)
            {
                printf("%d",nodes[path[i]].weight);
                if(i!=num-1) printf(" ");
                else printf("\n");
            }
            return;
        }
        else return;
    }
    else{
        for(int i=0;i<nodes[index].child.size();i++)
        {
            int child = nodes[index].child[i];
            path[num] = child;
            DFS(child,num+1,sum+nodes[child].weight);
        }
    }
}
int main()
{
    int t,n,c;
    scanf("%d%d%d",&N,&M,&S);
    for(int i=0;i<N;i++)
    {
        scanf("%d",&nodes[i].weight);
    }
    for(int i=0;i<M;i++)
    {
        scanf("%d%d",&t,&n);
        for(int j=0;j<n;j++)
        {
            scanf("%d",&c);
            nodes[t].child.push_back(c);
        }
        sort(nodes[t].child.begin(),nodes[t].child.end(),cmp);
    }
    path[0]=0;
    DFS(0,1,nodes[0].weight);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值