树的直径
树的直径
http://www.nowcoder.com/questionTerminal/a77b4f3d84bf4a7891519ffee9376df3
表面说是树,实际上是无向图的遍历。
树的直径就是两个节点之间最远的距离,而距离跟边权值有关。
所以要进行两次遍历,并在每次遍历记录比较出最大的边权值和
- 找到从根节点开始的最远的节点
- 从这个最远的节点出发找到最远的令一个节点
import java.util.*;
/*
* public class Interval {
* int start;
* int end;
* }
*/
public class Solution {
/**
* 树的直径
* @param n int整型 树的节点个数
* @param Tree_edge Interval类一维数组 树的边
* @param Edge_value int整型一维数组 边的权值
* @return int整型
*/
List<List<Integer>> graph = new ArrayList<>(); //用来存图结构
Map<Integer, Map<Integer,Integer>> table =new HashMap<>(); //用来存图权重
int maxEdges=0;
int maxIndex=-1;
public int solve (int n, Interval[] Tree_edge, int[] Edge_value) {
// write code here
for(int i=0; i<n; i++){
graph.add( new ArrayList<Integer>());
}
//构建graph,和table用于查询各边的权重
for(int i=0; i<Tree_edge.length;i++){
Interval edge=Tree_edge[i];
graph.get(edge.start).add(edge.end); //建立图
graph.get(edge.end).add(edge.start); //因为是无向图,所以也得反向连接一下
//构建表
if(!table.containsKey(edge.start)) table.put(edge.start, new HashMap<Integer, Integer>());
table.get(edge.start).put(edge.end,Edge_value[i]);
if(!table.containsKey(edge.end)) table.put(edge.end, new HashMap<Integer, Integer>());
table.get(edge.end).put(edge.start,Edge_value[i]);
}
//找到从根节点开始遍历到的最大边权值和的节点
dfs(0,0,-1);
//再从这个节点找到最大边权值和的节点
dfs(0,maxIndex,-1);
//返回最大边权值和
return maxEdges;
}
public void dfs(int count, int node, int parent){
List<Integer> cur = graph.get(node);
for(int i=0; i<cur.size(); i++){ //可行性剪枝?反正就是不允许dfs往回走到父节点
if(cur.get(i)==parent){
continue;
}
int value=table.get(node).get(cur.get(i));
//每一轮都加上边权值,遍历到最深的时候, count就是边权值和了
dfs(count+value, cur.get(i),node);
}
//每个边权值和进行比较
if(count>maxEdges){
//用maxEdges记录最大的边权值和
maxEdges=count;
//用maxIndex记录到达的最深的节点
maxIndex=node;
}
}
}

