小团找到一颗有n个节点的苹果树,以1号节点为根,且每个节点都有一个苹果,苹果都有一个颜色,但是这棵树被施加了咒术,这使得小团只能从某一个节点的子树中选取某一种颜色的拿。小团想要拿到数量最多的那种颜色的所有苹果,请帮帮她。每次她会指定一个节点t,如果小团只能从节点t的子树中选取某一种颜色的苹果,选取什么颜色能拿到最多的苹果?如果有多种颜色都可以拿同样多的苹果,输出颜色编号最小的那个对应的编号。
节点x的子树定义为所有将x当作祖先的节点,x也视为x的子树的一部分。
小团找到一颗有n个节点的苹果树,以1号节点为根,且每个节点都有一个苹果,苹果都有一个颜色,但是这棵树被施加了咒术,这使得小团只能从某一个节点的子树中选取某一种颜色的拿。小团想要拿到数量最多的那种颜色的所有苹果,请帮帮她。每次她会指定一个节点t,如果小团只能从节点t的子树中选取某一种颜色的苹果,选取什么颜色能拿到最多的苹果?如果有多种颜色都可以拿同样多的苹果,输出颜色编号最小的那个对应的编号。
节点x的子树定义为所有将x当作祖先的节点,x也视为x的子树的一部分。
第一行一个正整数n表示这颗树上节点的个数。
接下来n-1行,每行两个正整数xi,yi,表示树上第i条边连接的两个节点。
接下来一行n个正整数ci,分别表示从1~n号节点上的苹果的颜色。
接下来一行一个正整数q,表示接下来有q次独立的询问。
接下来q行,每行一个正整数t表示询问:如果小团只能从节点t的子树中选取某一种颜色的苹果,选取什么颜色能拿到最多的苹果?如果有多种颜色都可以拿同样多的苹果,输出颜色编号最小的那个对应的编号。
对于100%的数据n≤5000, 1≤xi,yi,t≤n, ci≤1000000000,q≤1000
输出q行,每行一个整数,表示答案。
7 1 2 1 3 2 4 2 5 3 6 3 7 1 1 2 1 2 2 3 7 1 2 3 4 5 6 7
1 1 2 1 2 2 3
import java.util.*; public class Main { public static void main(String[] args) { // 因为是不成环的图所以边数为节点数 - 1 Scanner sc = new Scanner(System.in); int nodeNum = sc.nextInt(); // 先使用ColorNode[]来存储所有结点并构建:无向无权不成环的图 ColorNode[] nodes = new ColorNode[nodeNum + 1]; for (int i = 0; i < nodeNum - 1; i++) { int u = sc.nextInt(); int v = sc.nextInt(); if (nodes[u] == null) { nodes[u] = new ColorNode(); } if (nodes[v] == null) { nodes[v] = new ColorNode(); } nodes[v].subTree.add(nodes[u]); nodes[u].subTree.add(nodes[v]); } // 无向图变为有向图 modify(nodes[1]); sc.nextLine(); // 设置颜色 String[] split = sc.nextLine().split(" "); for (int i = 1; i <= nodeNum; i++) { nodes[i].color = Integer.valueOf(split[i - 1]); } // 记录开始的结点编号 int loop = sc.nextInt(); int[] res = new int[loop]; int[] opNum = new int[loop]; sc.nextLine(); for (int i = 0; i < loop; i++) { opNum[i] = Integer.valueOf(sc.nextLine()); } // 遍历要操作的结点 for (int i = 0; i < loop; i++) { int opeNode = opNum[i]; // 深搜并将结果保存在map中 HashMap<Integer, Integer> map = new HashMap<>(); dfs(nodes[opeNode], map); // 按照value降序排序 List<Map.Entry<Integer, Integer>> list = new ArrayList<>(map.entrySet()); Collections.sort(list, (Map.Entry<Integer, Integer> entry1, Map.Entry<Integer, Integer> entry2) -> { return entry2.getValue() - entry1.getValue(); }); // 找到符合要求的颜色 int curRes = list.get(0).getKey(); int curMaxNum = list.get(0).getValue(); int j = 1; // 如果出现重复的最大数量颜色编号,则找到最小的那个 while (j < list.size() && list.get(j).getValue() == curMaxNum) { curRes = list.get(j).getKey() < curRes ? list.get(j).getKey() : curRes; j++; } // 保存结点 res[i] = curRes; } // 打印结果 for (int i = 0; i < res.length; i++) { System.out.println(res[i]); } } // 深搜:类似前序遍历 public static void dfs(ColorNode root, HashMap<Integer, Integer> map) { if (root == null) return; int color = root.color; Integer aDefault = map.getOrDefault(color, -1); if (aDefault == -1) { // 说明当前颜色第一次被检测到 map.put(color, 1); } else { map.put(color, aDefault + 1); } for (ColorNode subNode : root.subTree) { dfs(subNode, map); } } // 从无向树变为有向树(层序遍历) public static void modify(ColorNode root) { ArrayDeque<ColorNode> deque = new ArrayDeque<>(); deque.addLast(root); while (deque.size() != 0) { int size = deque.size(); for (int i = 0; i < size; i++) { ColorNode first = deque.removeFirst(); for (ColorNode curSub : first.subTree) { deque.addLast(curSub); curSub.subTree.remove(first); } } } } static class ColorNode { int color; ArrayList<ColorNode> subTree; public ColorNode() { this.color = -1; this.subTree = new ArrayList<>(); } } }
import java.util.*; class TreeNode{ int val; int color; List<TreeNode> Friend =new ArrayList<>(); public TreeNode(int val){ this.val=val; } } public class Main{ public static void modify(TreeNode root){ if(root.Friend.size()==0){ return; } for (TreeNode node : root.Friend) { node.Friend.remove(root); modify(node); } } public static void dfs(TreeNode root,Map<Integer,Integer> colormap){ if(root==null)return; colormap.put(root.color, colormap.getOrDefault(root.color,0)+1); for (TreeNode treeNode : root.Friend) { dfs(treeNode,colormap); } } public static void main(String[] args){ /*第一行一个正整数n表示这颗树上节点的个数。 接下来n-1行,每行两个正整数xi,yi,表示树上第i条边连接的两个节点。 接下来一行n个正整数ci,分别表示从1~n号节点上的苹果的颜色。 接下来一行一个正整数q,表示接下来有q次独立的询问。 接下来q行,每行一个正整数t表示询问:如果小团只能从节点t的子树中选取某一种颜色的苹果,选取什么颜色能拿到最多的苹果? 如果有多种颜色都可以拿同样多的苹果,输出颜色编号最小的那个对应的编号。 节点x的子树定义为所有将x当作祖先的节点,x也视为x的子树的一部分。 */ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); Map<Integer, TreeNode> map=new HashMap<>(); for(int i=0;i<n-1;i++){ int x=sc.nextInt(); int y=sc.nextInt(); TreeNode node1=map.get(x); TreeNode node2=map.get(y); if(node1==null)node1=new TreeNode(x); if(node2==null)node2=new TreeNode(y); node1.Friend.add(node2); node2.Friend.add(node1); map.put(x,node1); map.put(y,node2); } modify(map.get(1)); for(int i=1;i<=n;i++){ int color=sc.nextInt(); map.get(i).color=color; } int q=sc.nextInt(); for(int i=0;i<q;i++){ Map<Integer,Integer> colormap=new HashMap<>(); int t=sc.nextInt(); TreeNode root=map.get(t); dfs(root,colormap); int bestColor=0; int count=0; for (Map.Entry<Integer, Integer> entry : colormap.entrySet()) { if(entry.getValue()==count)bestColor=Math.min(entry.getKey(),bestColor); else if(entry.getValue()>count){ bestColor=entry.getKey(); count=entry.getValue(); } } System.out.println(bestColor); } } }