阿里巴巴的ODPS大数据处理平台可以启动一系列并发的作业,每个作业中存在一系列存在父子关系的任务。每个任务用一个三元组表示–(任务id,父任务id,执行开销),其中任务id是一个正整数(>0);父任务id为0表示根任务,每个作业存在一个唯一的根任务,并且,所有的任务,如果其父任务id不为0,那么必然是一个已经存在的根任务id;执行开销是一个正整数(>0)。系统中至少存在一个作业。
举例如下:
(1,0,2)(2,0,3)(3,1,2)(4,1,3)
对应的任务关系是:
注:括号内的数字表示任务开销
很容易看出来,这些任务树构成了一个森林。每颗任务树有若干个叶子结点,从根节点到叶子结点的路径上所有的执行开销,称作叶子结点对应的任务的总开销。例如上面一共有3个叶子结点任务,分别是任务3,4和2,对应的总开销分别是4,5和3,总开销最大的叶子结点任务是4,对应的总开销是5。
现在需要编写程序,针对输入的任务数据,找到总开销最大的叶子结点任务对应的总开销,比如针对上面例子,输出5。
示例输入:
1 0 2
2 0 3
3 1 2
4 1 3
0
示例输出:
5
这是阿里的一道编程测试题,限时四十分钟。这道题我刚看到的第一直觉就是一个多叉树问题,只有一个根节点,每个结点下面都有0或若干个子节点(包括根节点)。可以先利用输入构造出一个多叉树,然后便利多叉树的每一条从根结点到叶子结点的路径,来求出最优解。
首先定义一个树节点类:
class TreeNode{
/** 节点Id*/
private int nodeId;
/** 父节点Id*/
private int parentId;
/** 开销*/
private int cost;
public TreeNode(int nodeId, int parentId, int cost)
{
this.nodeId = nodeId;
this.parentId = parentId;
this.cost = cost;
}
public int getNodeId() {
return nodeId;
}
public void setNodeId(int nodeId) {
this.nodeId = nodeI