fork download
  1. import java.util.*;
  2. import java.io.*;
  3.  
  4. public class Main {
  5. static List<Integer>[] tree;
  6. static char[] color;
  7. static long[] weight;
  8. static long minCost = Long.MAX_VALUE;
  9.  
  10. public static void main(String[] args) throws IOException {
  11. int n = Integer.parseInt(br.readLine());
  12. color = br.readLine().trim().toCharArray();
  13. weight = new long[n];
  14. StringTokenizer st = new StringTokenizer(br.readLine());
  15. for (int i = 0; i < n; i++) {
  16. weight[i] = Long.parseLong(st.nextToken());
  17. }
  18.  
  19. tree = new ArrayList[n];
  20. for (int i = 0; i < n; i++) tree[i] = new ArrayList<>();
  21. for (int i = 0; i < n - 1; i++) {
  22. st = new StringTokenizer(br.readLine());
  23. int u = Integer.parseInt(st.nextToken()) - 1;
  24. int v = Integer.parseInt(st.nextToken()) - 1;
  25. tree[u].add(v);
  26. tree[v].add(u);
  27. }
  28.  
  29. // 遍历每个节点作为可能的根节点
  30. for (int root = 0; root < n; root++) {
  31. char target = color[root];
  32. long[] totalCost = new long[1];
  33. boolean[] visited = new boolean[n];
  34. dfs(root, -1, target, totalCost, visited);
  35. minCost = Math.min(minCost, totalCost[0]);
  36. }
  37.  
  38. System.out.println(minCost);
  39. }
  40.  
  41. // 返回是否需要修改该子树
  42. static boolean dfs(int node, int parent, char target, long[] totalCost, boolean[] visited) {
  43. visited[node] = true;
  44. boolean needModify = (color[node] != target);
  45. long subtreeWeight = weight[node];
  46.  
  47. for (int child : tree[node]) {
  48. if (child != parent && !visited[child]) {
  49. boolean childNeedModify = dfs(child, node, target, totalCost, visited);
  50. if (childNeedModify) {
  51. needModify = true;
  52. }
  53. subtreeWeight += weight[child];
  54. }
  55. }
  56.  
  57. if (needModify && parent != -1) { // 非根节点才需要计算修改代价
  58. totalCost[0] += subtreeWeight;
  59. }
  60. return needModify;
  61. }
  62. }
Success #stdin #stdout 0.08s 52976KB
stdin
4
RGBR
3 1 2 4
1 2
2 3
2 4
stdout
8