1207. 大臣的旅费 蓝桥 邻接表(前向星)树的直径 BFS/DFS 求距离

大臣的旅费
🤬 受教:卡缓冲流
在这里插入图片描述
在这里插入图片描述
输入样例

5 
1  2  2 
1  3  1 
2  4  5 
2  5  4 

输出样例

135

⭐ 树的直径:任意一点 x ,取距离 x 最远的点 y,再找距离 y 最远的点 z,y - z 就是树的直径
⭐ 树中相距最远的两点的距离
在这里插入图片描述
⭐ 计算费用
在这里插入图片描述

👨‍🏫 注意
在这里插入图片描述

import java.io.*;
import java.util.*;

public class Main
{
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

	static int N = 100010, idx;
	static int M = 2 * N;
	static int[] e = new int[M];
	static int[] ne = new int[M];
	static int[] w = new int[M];
	static int[] h = new int[N];
	static int[] dist = new int[N];

	public static void main(String[] args) throws IOException
	{
//		String[] ss = in.readLine().split(" ");
//		int n = Integer.parseInt(ss[0]);

		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();

		Arrays.fill(h, -1);
		for (int i = 1; i < n; i++)
		{
//			ss = in.readLine().split("  ");
//			int a = Integer.parseInt(ss[0]);
//			int b = Integer.parseInt(ss[1]);
//			int c = Integer.parseInt(ss[2]);
			int a = sc.nextInt();
			int b = sc.nextInt();
			int c = sc.nextInt();
			add(a, b, c);
			add(b, a, c);
		}

		dfs(1, -1, 0);
		int u = 1;
		for (int i = 2; i <= n; i++)
		{
			if (dist[i] > dist[u])
				u = i;
		}

//		此时 u (y) 是 距离 x 最远的点
		dfs(u, -1, 0);

//		找到距离 u 最远的节点
		int md = dist[1];
		for (int i = 2; i <= n; i++)
			if (dist[i] > md)
				md = dist[i];
//		推公式: 10 * md + 前n项和
		System.out.println(md * 10 + (long) md * (md + 1) / 2);
	}

//	DFS 树并记录节点到根节点的距离
//  u 当前节点,father 父节点(不走回头路),distance 到根节点的距离
	private static void dfs(int u, int father, int distance)
	{
		dist[u] = distance;
		for (int i = h[u]; i != -1; i = ne[i])
		{
			int j = e[i];
			if (j != father)
				dfs(j, u, distance + w[i]);
		}
	}

//	添加 a 指向 b 的边 权值为 c
	private static void add(int a, int b, int c)
	{
		e[idx] = b;
		ne[idx] = h[a];
		w[idx] = c;
		h[a] = idx++;
	}
}

posted @ 2023-03-31 22:12  兑生  阅读(19)  评论(0)    收藏  举报  来源
Live2D