DSAA B第三次assignment q2 paths(南科大)

一. Problem Description

Given a rooted tree numbered from 1 to n , each edge has a weight w . The root node of the tree is

node 1 . You are asked to calculate the number of paths that start from the root, terminate in a

leaf node, and satisfy the sum of edge weights in the path equals to nums.

Input

The first line contains two integers n and num indicating the number of tree nodes and the target number.

Then n-1 lines follow. Each line contains three integers u,v,w describing an edge.

The first two integers are the indices of nodes that form an edge and the lastinteger indicates the weight of the edge.

Output

Output an integer which means how many paths satisfying the sum of edge weights in the pathequals to nums.

.Sample input

6 6
1 2 2
1 3 3
3 4 4
3 5 3
2 6 4

Sample output

2

二. 解题思路

使用dfs遍历求解(求解思路比较粗暴)

  1. 子类方法 link 包含两个元素,代表连杆之间的重量和目标值。

class link{
    int weight;
    int def;
}
  1. 连杆创建

  LinkedList<link> []list=new LinkedList[n+1];
        //创建一个空的Linkedlist数组,并且为内部的linkedlist创建空间
        for( int i = 0; i < list.length; i ++ ){
            list[i] = new LinkedList<>();
        }
        for (int i = 0; i < n-1; i++) {
            //数据读入
            int n1=in.nextInt();
            int n2=in.nextInt();
            int weight=in.nextInt();
            //创建并连接连杆link
            link x=new link();link y=new link();
            x.def=n2;y.def=n1;
            x.weight=weight; y.weight=weight;
            list[n1].add(x);list[n2].add(y);
        }
  1. 调用dfs递归,从根节点开始,每次对子节点进行剪枝,并且继续从子节点开始递归,并且每次递归改变weight的值,当子节点的list无子集之后,将累积的weight值与nums进行对比,并且返回1or0,最后累积总数

三. 代码示例

import java.io.File;
import java.io.FileNotFoundException;
import java.util.LinkedList;
import java.util.Scanner;
 class link{
    int weight;
    int def;
}

public class Paths{
    public static void main(String[] args) throws FileNotFoundException {
        // 文件中第一个数字是数组长度,接下来N个数字才是数组元素。
        // 请根据实际情况更改文件路径
        File input = new File("test_data/Q2/B1.in");
        if (!input.exists()) {
            System.out.println("File isn't exist");
            System.exit(0);
        }
        Scanner in = new Scanner(input);
        int n = in.nextInt(); //the number of tree nodes
        int num = in.nextInt();// the target number
        LinkedList<link> []list=new LinkedList[n+1];
        //创建一个空的Linkedlist数组,并且为内部的linkedlist创建空间
        for( int i = 0; i < list.length; i ++ ){
            list[i] = new LinkedList<>();
        }
        for (int i = 0; i < n-1; i++) {
            //数据读入
            int n1=in.nextInt();
            int n2=in.nextInt();
            int weight=in.nextInt();
            //创建并连接连杆link
            link x=new link();link y=new link();
            x.def=n2;y.def=n1;
            x.weight=weight; y.weight=weight;
            list[n1].add(x);list[n2].add(y);
        }

        int pathNmuber = findPaths(num,list);

        File output = new File("test_data/Q2/B1.out");
        in = new Scanner(output);
        boolean flag = in.nextInt() == pathNmuber;
        System.out.println(flag);
    }
    public static int findPaths(int num, LinkedList<link> [] list) {
        int answer=0;
        while(list[1].size()!=0){
        answer=answer+dfs(list,num,1,0,0);}//逐一遍历根节点的子节点
         return answer;
    }
    public static int dfs( LinkedList<link> [] list,int num,int father,int child,int weight){
        int answer=0;
        int th=list[father].get(child).def;
       weight=weight+list[father].get(child).weight;
        list[father].remove(child);

        for (int i = 0; i <list[th].size() ; i++) {
            if (list[th].get(i).def==father){
                list[th].remove(i);
                break;
            }
        }
        if (list[th].size()!=0) {
            while (list[th].size() != 0)
                answer = answer + dfs(list, num, th, 0, weight);
        }
       else {
            if (weight == num) {
                return 1;
            }
        }
        return answer;
    }
   
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值