問題の説明
木が与えられた場合、木の直径、つまり、木の最も遠い2点間の距離を見つけます。
入力の説明:
入力ノードの数、各エッジの2つのノード、エッジの重み
出力の説明:
最長のパスを出力します
例
例1
入力
6、[0,1]、[1,5]、[1,2]、[2,3]、[2,4]、[3,4,2,1,5]
出力
11
ソリューション
分析
この質問は主に深さ優先探索によるものであり、最大値は各パスの重み値を比較して判断することによって得られます。
方法
- 深さ優先トラバーサルを使用して、ツリーをトラバースして最大値を取得します
コード
public class Solution {
/**
* 树的直径
*
* @param n int整型 树的节点个数
* @param Tree_edge Interval类一维数组 树的边
* @param Edge_value int整型一维数组 边的权值
* @return int整型
*/
//6,[[0,1],[1,5],[1,2],[2,3],[2,4]],[3,4,2,1,5]
int res = 0;
public int solve(int n, Interval[] Tree_edge, int[] Edge_value) {
// write code here
// list数组存储每个节点的所有边
List<int[]>[] map = new ArrayList[n];
// 将所有的节点初始化
for (int i = 0; i < n; i++) map[i] = new ArrayList();
// 遍历所有的边,一次添加到对应数组的list中
for (int i = 0; i < Tree_edge.length; i++) {
// 起始节点的边,存储终节点和边的权重值
map[Tree_edge[i].start].add(new int[]{
Tree_edge[i].end, Edge_value[i]});
// 终节点的边,存储起节点和权重值
map[Tree_edge[i].end].add(new int[]{
Tree_edge[i].start, Edge_value[i]});
}
// 深度优先遍历,通过数组的bool值判断节点是否已经访问过
dfs(map, 0, new boolean[n]);
return res;
}
private int dfs(List<int[]>[] map, int index, boolean[] visited) {
// 将节点置为已经访问
visited[index] = true;
// 获取节点的所有的边
List<int[]> list = map[index];
int weight1 = 0, weight2 = 0;
// 遍历所有的边
for (int[] child2weight : list) {
// 获取边的另一端
int child = child2weight[0];
// 获取边的权重
int weight = child2weight[1];
// 判断边是否已经访问
if (visited[child]) continue;
// 计算路径长度
int num = weight + dfs(map, child, visited);
if (num > weight1) {
weight2 = weight1;
weight1 = num;
} else if (num > weight2) {
weight2 = num;
}
if (weight1 + weight2 > res) res = weight1 + weight2;
}
return Math.max(weight1, weight2);
}
}
テストしたい場合は、Niuke.comのリンクに直接アクセスしてテストを行うことができます