import java.util.LinkedList;
import java.util.List;
import java.util.ArrayList;
import java.util.Queue;
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
private static List<List<Integer>> adjacencyList;
private static boolean[] visited;
private static int[] distance;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean oddExist = false;
int maxHalfStrLen = 0;
for (int i = 0; i < 26; i++) {
int nChar = in.nextInt();
if (nChar % 2 == 1) oddExist = true;
maxHalfStrLen += nChar / 2;
}
int maxStrLen = oddExist ? (maxHalfStrLen * 2 + 1) : (maxHalfStrLen * 2);
// 读取节点个数 n
int n = in.nextInt();
adjacencyList = new ArrayList<>(n + 1); // 节点编号从 1 到 n
for (int i = 0; i <= n; i++) {
adjacencyList.add(new ArrayList<>());
}
// 读取 n-1 条边并构建无向图
for (int k = 0; k < n - 1; k++) {
int i = in.nextInt();
int j = in.nextInt();
adjacencyList.get(i).add(j);
adjacencyList.get(j).add(i);
}
// 计算树的直径
int diameter = computeTreeDiameter(n) + 1;
int result = (diameter > maxStrLen) ? maxStrLen : diameter;
System.out.println(result);
}
private static int computeTreeDiameter(int n) {
// 第一次 BFS 找到最远的节点 u
visited = new boolean[n + 1];
distance = new int[n + 1];
bfs(1); // 从任意节点开始(这里选择节点1)
int u = 1;
int maxDistance = 0;
for (int i = 1; i <= n; i++) {
if (distance[i] > maxDistance) {
maxDistance = distance[i];
u = i;
}
}
// 第二次 BFS 从 u 出发找到最远的节点 v
visited = new boolean[n + 1];
distance = new int[n + 1];
bfs(u);
int v = 1;
maxDistance = 0;
for (int i = 1; i <= n; i++) {
if (distance[i] > maxDistance) {
maxDistance = distance[i];
v = i;
}
}
// 最长路径就是 u 到 v 的距离
return maxDistance;
}
private static void bfs(int start) {
Queue<Integer> queue = new LinkedList<>();
queue.offer(start);
visited[start] = true;
distance[start] = 0;
while (!queue.isEmpty()) {
int current = queue.poll();
for (int neighbor : adjacencyList.get(current)) {
if (!visited[neighbor]) {
visited[neighbor] = true;
distance[neighbor] = distance[current] + 1;
queue.offer(neighbor);
}
}
}
}
}
事实上,这题纯粹是两个简单问题的杂糅。
前一个问题是,给定若干个字母,问组成的最长回文字符串长度maxStrLen;
后一个问题是,给定一棵树,问最长路径上的节点数diameter;
然后输出二者中较小的那个就好。



京公网安备 11010502036488号