利用邻接表进行图的深度搜索
小美的美丽树
https://www.nowcoder.com/questionTerminal/f4161b1bac304f5b803fed3e3758d4bb?f=discussion
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.HashMap; import java.util.ArrayList; public class Main { static boolean[] visited; // 标记节点是否已经被访问 static int[] weight; // 节点权值 static int[] childNum; // 存储以节点i为根的树有多少个节点 static int[] max, min; // 存储以节点i为根的子树下的最大值和最小值 // 节点间的最大差值 static int maxDiff = -1; // 待求节点 static int node = -1; // 邻接表 static HashMap<Integer, ArrayList<Integer>> tree; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] temp = br.readLine().trim().split(" "); int n = Integer.parseInt(temp[0]); int k = Integer.parseInt(temp[1]); temp = br.readLine().trim().split(" "); weight = new int[n + 1]; for(int i = 1; i <= n; i++) weight[i] = Integer.parseInt(temp[i - 1]); int x, y; // 构建树图的邻接表 tree = new HashMap<>(); ArrayList<Integer> list; for(int i = 1; i <= n - 1; i++){ temp = br.readLine().trim().split(" "); x = Integer.parseInt(temp[0]); y = Integer.parseInt(temp[1]); if(tree.containsKey(x)){ list = tree.get(x); list.add(y); tree.put(x, list); }else{ list = new ArrayList<>(); list.add(y); tree.put(x, list); } if(tree.containsKey(y)){ list = tree.get(y); list.add(x); tree.put(y, list); }else{ list = new ArrayList<>(); list.add(x); tree.put(y, list); } } int root = Integer.parseInt(br.readLine().trim()); visited = new boolean[n + 1]; max = new int[n + 1]; min = new int[n + 1]; childNum = new int[n + 1]; dfs(root, k); System.out.println(node); } //求取parent下面的最值 public static void dfs(int parent, int k){ visited[parent] = true; // 初始化parent下的最值为parent的节点权重 max[parent] = weight[parent]; min[parent] = weight[parent]; // 初始情况下,该子树只有一个节点 childNum[parent] = 1; for(int i = 0; i < tree.get(parent).size(); i++){ int child = tree.get(parent).get(i); if(!visited[child]){ // 没访问过这个孩子节点就进行深搜 dfs(child, k); max[parent] = Math.max(max[parent], max[child]); min[parent] = Math.min(min[parent], min[child]); childNum[parent] += childNum[child]; } } if(childNum[parent] <= k && max[parent] - min[parent] >= maxDiff){ // 以parent为根节点的子树满足节点数小于等于k,且最大差值大于等于目前最大 if(max[parent] - min[parent] > maxDiff){ // 大于了直接更新,等于的话需要考虑哪个根节点的编号小 node = parent; maxDiff = max[parent] - min[parent]; }else{ // 如果node还没有赋值,就直接赋值为当前节点,否则取满足要求的节点中编号最小的 node = node == -1? parent: Math.min(node, parent); } } } }
总结
图的DFS:
- 必须有个邻接表
HashMap<Integer, ArrayList<Integer>>
来记录相邻节点的关系,或者是矩阵。 - 标记数组
- 在限定条件下去进性深度优先搜索,再去更新一些我们要求的值