思路就是通过两次DFS/BFS确定多叉树(无向无环无负权图)的直径,这里提供java的两个版本,参考评论区的各位dalao([狗头保命])。
DFS:
BFS:
DFS:
import java.util.*;
/*
* public class Interval {
* int start;
* int end;
* }
*/
public class Solution {
private List<List<Edge>> graph;
private int maxDistance = 0; // 本次dfs最远距离
private int maxIndex = -1; // 本次dfs最远节点
/**
* 树的直径
*
* @param n int整型 树的节点个数
* @param Tree_edge Interval类一维数组 树的边
* @param Edge_value int整型一维数组 边的权值
* @return int整型
*/
public int solve(int n, Interval[] Tree_edge, int[] Edge_value) {
// 以邻接表的方式建立图
this.graph = new ArrayList<>(n);
// 初始化
for (int i = 0; i < n; i++) {
graph.add(new ArrayList<>());
}
for (int i = 0; i < Tree_edge.length; i++) {
// 由于是无向图,每条边都是双向的
graph.get(Tree_edge[i].start).add(new Edge(Tree_edge[i].end, Edge_value[i]));
graph.get(Tree_edge[i].end).add(new Edge(Tree_edge[i].start, Edge_value[i]));
}
dfs(0, -1, 0);
maxDistance = 0;
dfs(far, -1, 0);
return maxDistance;
}
private void dfs(int cur, int parent, int distance) {
if (distance > maxDistance) {
maxDistance = distance;
maxIndex = cur;
}
List<Edge> edges = graph.get(cur);
for (Edge edge : edges) {
int end = edge.end;
if (end == parent) { // 不能往回走到父节点
continue;
}
dfs(end, cur, distance + edge.weight);
}
}
// 邻接表的边结构
private class Edge {
int end; // 边的终点
int weight; // 权重
public Edge(int end, int weight) {
this.end = end;
this.weight = weight;
}
}
}
import java.util.*;
/*
* public class Interval {
* int start;
* int end;
* }
*/
public class Solution {
private List<List<Edge>> graph;
private int maxDistance = 0; // 本次dfs最远距离
private int maxIndex = -1; // 本次dfs最远节点
/**
* 树的直径
*
* @param n int整型 树的节点个数
* @param Tree_edge Interval类一维数组 树的边
* @param Edge_value int整型一维数组 边的权值
* @return int整型
*/
public int solve(int n, Interval[] Tree_edge, int[] Edge_value) {
// 以邻接表的方式建立图
this.graph = new ArrayList<>(n);
// 初始化
for (int i = 0; i < n; i++) {
graph.add(new ArrayList<>());
}
for (int i = 0; i < Tree_edge.length; i++) {
// 由于是无向图,每条边都是双向的
graph.get(Tree_edge[i].start).add(new Edge(Tree_edge[i].end, Edge_value[i]));
graph.get(Tree_edge[i].end).add(new Edge(Tree_edge[i].start, Edge_value[i]));
}
bfs(0); // 从节点0开始
maxDistance = 0;
bfs(maxIndex); //
return maxDistance;
}
private void bfs(int start) {
Queue<Node> queue = new LinkedList<>();
queue.offer(new Node(start, -1, 0));
while(!queue.isEmpty()) {
// 取出当前节点
Node node = queue.poll();
int cur = node.cur;
int parent = node.parent;
int distance = node.distance;
// 如果大于maxDistance,则进行更新
if (distance > maxDistance) {
maxDistance = distance;
maxIndex = cur;
}
List<Edge> edges = graph.get(cur);
for (Edge edge : edges) {
if (edge.end == parent) {
continue;
}
queue.offer(new Node(edge.end, cur, distance + edge.weight));
}
}
}
// 邻接表的边结构
private class Edge {
public int end; // 边的终点
public int weight; // 权重
public Edge(int end, int weight) {
this.end = end;
this.weight = weight;
}
}
// 保存遍历到当前节点时的各种信息
private class Node {
public int cur; // 当前节点
public int parent; // 父节点
public int distance; // 初始节点到当前节点的距离
public Node(int cur, int parent, int distance) {
this.cur = cur;
this.parent = parent;
this.distance = distance;
}
}
}

京公网安备 11010502036488号