博客
关于我
【Lintcode】291. Second Diameter
阅读量:188 次
发布时间:2019-02-28

本文共 3196 字,大约阅读时间需要 10 分钟。

题目地址:

给定一棵树型的无向带权图,求其次大直径(即所有两点距离 d ( v 1 , v 2 ) d(v_1,v_2) d(v1,v2)里第二大的,相等的距离也要参与计数)。

先求最大直径(第一直径)的两个端点 v 1 v_1 v1 v 2 v_2 v2,则 max ⁡ u ≠ v 2 d ( v 1 , u ) \max_{u\ne v_2} d(v_1, u) maxu=v2d(v1,u) max ⁡ u ≠ v 1 d ( v 2 , u ) \max_{u\ne v_1} d(v_2, u) maxu=v1d(v2,u)的最大值即为所求。而求最远点距离可以用BFS来做(主要是为了防止DFS爆栈)。

算法正确性证明:

首先,参考可知从任意点出发找到的最远距离的点一定是直径的一个端点,那么第二直径一定有某个点不是 v 1 v_1 v1或者 v 2 v_2 v2,但是第二直径的非第一直径的端点的那个端点出发,最远距离一定是到达了直径的某个端点的,换言之,第二直径可以从第一直径的某个端点出发,搜到最远的非 v 1 v_1 v1或者 v 2 v_2 v2的点的距离,就是第二直径长度。

代码如下:

import java.util.*;public class Solution {           private long res;        /**     * @param edge: edge[i][0] [1] [2]  start point,end point,value     * @return: return the second diameter length of the tree     */    public long getSecondDiameter(int[][] edge) {           // write your code here        // 顶点数是边数加1        int n = edge.length + 1;        Map
> graph = buildGraph(edge); // 先找到直径的两个端点 int far1 = bfs(0, graph, -1, new boolean[n]); int far2 = bfs(far1, graph, -1, new boolean[n]); // 然后分别从两个端点出发,计算除去另一个端点的情况下的最远距离 bfs(far1, graph, far2, new boolean[n]); bfs(far2, graph, far1, new boolean[n]); return res; } // 返回与v离得最远的,但不是u的点的编号。同时当u不是直径端点的时候,更新res private int bfs(int v, Map
> graph, int u, boolean[] visited) { Queue
queue = new LinkedList<>(); queue.offer(new long[]{ v, 0}); visited[v] = true; // farV存离v最远的点(可能要排除u) int farV = v; // 存v离farV的距离 long farDis = 0; while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { long[] cur = queue.poll(); int nextV = (int) cur[0]; if (graph.containsKey(nextV)) { for (int[] next : graph.get(nextV)) { // 忽略掉第一直径的端点 if (next[0] != u && !visited[next[0]]) { // 为了找到离v最远的点,如果找到更远距离了,则更新距离和遇到的点 if (next[1] + cur[1] > farDis) { farDis = next[1] + cur[1]; farV = next[0]; } visited[next[0]] = true; queue.offer(new long[]{ next[0], next[1] + cur[1]}); } } } } } // 只有其中一个点不是第一直径的时候,才能更新答案 if (u != -1) { res = Math.max(res, farDis); } return farV; } // 邻接表建图,value的[0]存的是与key连接的顶点编号,[1]存的是边长 private Map
> buildGraph(int[][] edges) { Map
> graph = new HashMap<>(); for (int[] edge : edges) { graph.putIfAbsent(edge[0], new ArrayList<>()); graph.get(edge[0]).add(new int[]{ edge[1], edge[2]}); graph.putIfAbsent(edge[1], new ArrayList<>()); graph.get(edge[1]).add(new int[]{ edge[0], edge[2]}); } return graph; }}

时空复杂度 O ( n ) O(n) O(n) n n n是树的顶点个数。

转载地址:http://adjs.baihongyu.com/

你可能感兴趣的文章
mysql 5.6 修改端口_mysql5.6.24怎么修改端口号
查看>>
mui折叠面板点击事件跳转
查看>>
MySQL 8 公用表表达式(CTE)—— WITH关键字深入用法
查看>>
mysql 8 远程方位_mysql 8 远程连接注意事项
查看>>
MUI框架里的ajax的三种方法
查看>>
MySQL 8.0 恢复孤立文件每表ibd文件
查看>>
Mysql 8.0 新特性
查看>>
MultCloud – 支持数据互传的网盘管理
查看>>
MySQL 8.0.23中复制架构从节点自动故障转移
查看>>
MySQL 8.0开始Group by不再排序
查看>>
mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
查看>>
multi swiper bug solution
查看>>
MySQL Binlog 日志监听与 Spring 集成实战
查看>>
MySQL binlog三种模式
查看>>
multi-angle cosine and sines
查看>>
Mysql Can't connect to MySQL server
查看>>
mysql case when 乱码_Mysql CASE WHEN 用法
查看>>
Multicast1
查看>>
mysql client library_MySQL数据库之zabbix3.x安装出现“configure: error: Not found mysqlclient library”的解决办法...
查看>>
MySQL Cluster 7.0.36 发布
查看>>