小团找到一颗有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);
}
}
}