【题目描述】
AcWing 1207. 大臣的旅费
n个点,(n-1)条边。实质上本题就是一个无向图,两两之间只有唯一路径,不存在环,要相距最远两个点的距离,就是树的直径问题。
【思路】
先从任意点开始dfs找到距离最远的点u,该点即为直径的起点。再以该点u为起点dfs获得最远距离即为直径。
MEL代码
Vector 写法
最后一个数据过不了,栈溢出
import java.util.Scanner;
import java.util.Vector;
class Edge{
int id, w;
public Edge(int idd, int ww){
id = idd;
w = ww;
}
}
class Main{
static int N = 100010;
static Vector<Edge> q[];
static int []dist = new int[N];
static int n;
/*
u :当前节点
father: 记录从father节点来
distance: 表示当前节点u到起始点的总路径长度。.
*/
public static void dfs(int u, int father, int distance){
dist[u] = distance;
for(Edge e: q[u]){//枚举与u城市相邻的节点
if( e.id != father){
dfs(e.id, u, distance + e.w);
}
}
}
public static void main(String agrs[]){
Scanner reader = new Scanner(System.in);
n = reader.nextInt();
//初始化为N个空的vector, 表示每一个q[i]都为空
q = new Vector[N];
//每个q[i]是Edge类型的数组
for(int i = 0; i <= n; i ++)
q[i] = new Vector<Edge>();
for(int i = 0; i < n - 1; i++){
int a = reader.nextInt(), b = reader.nextInt(), c = reader.nextInt();
q[a].add( new Edge(b, c));
q[b].add( new Edge(a, c));
}
//从任意一点(假设为1)出发 距离最远的点就是树的直径的端点
//dist[i]记录从起始点1到i的距离
dfs(1, -1, 0);
int u = 1;
for(int i = 1; i <= n; i++)
if(dist[i] > dist[u]) u = i;
//dist[i]记录从起始点u到i的距离 max(dist<u,i>)为直径
dfs(u, -1, 0);
for(int i = 1; i <= n; i++)
if(dist[i] > dist[u]) u = i;
long s = dist[u];
//等差数列 :首项为11 公差为1
System.out.println( (21 + s)*s/2 );
}
}
数组写法
数组写法可以全过,但看不是太懂
import java.util.Arrays;
import java.util.Scanner;
public class Main{
static int N = 100010, M = 200010; //N 最大城市个数 M最多边数
static int [] h = new int[M];
static int [] e = new int[M];
static int [] ne = new int[M];
static int [] w = new int[M];
static int [] dist = new int[N];
static int idx = 0;
public static void add(int a, int b, int c){
e[idx] = b;
w[idx] = c;
ne[idx] = h[a];
h[a] = idx ++; //
}
public 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]);
}
}
public static void main(String args[]){
Scanner reader = new Scanner(System.in);
int n = reader.nextInt();
Arrays.fill(h, - 1);
for(int i = 0; i < n - 1; i++){
int a = reader.nextInt();
int b = reader.nextInt();
int c = reader.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;
dfs(u, -1, 0);
for(int i = 1; i <= n; i ++)
if(dist[i] > dist[u])
u = i;
long s = dist[u];
System.out.println( (21 + s) * s /2);
}
}