#1062 : 最近公共祖先·一
阿新 • • 發佈:2019-02-03
輸入
每個測試點(輸入檔案)有且僅有一組測試資料。
每組測試資料的第1行為一個整數N,意義如前文所述。
每組測試資料的第2~N+1行,每行分別描述一對父子關係,其中第i+1行為兩個由大小寫字母組成的字串Father_i, Son_i,分別表示父親的名字和兒子的名字。
每組測試資料的第N+2行為一個整數M,表示小Hi總共詢問的次數。
每組測試資料的第N+3~N+M+2行,每行分別描述一個詢問,其中第N+i+2行為兩個由大小寫字母組成的字串Name1_i, Name2_i,分別表示小Hi詢問中的兩個名字。
對於100%的資料,滿足N<=10^2,M<=10^2, 且資料中所有涉及的人物中不存在兩個名字相同的人(即姓名唯一的確定了一個人)。
輸出
對於每組測試資料,對於每個小Hi的詢問,輸出一行,表示查詢的結果:如果根據已知資訊,可以判定詢問中的兩個人存在共同的祖先,則輸出他們的所有共同祖先中輩分最低的一個人的名字,否則輸出-1。
思路:
先用其中一個來回溯到根,記錄路徑上的節點為訪問過,再用另一個來回溯到根,期間只要第一次碰到已經訪問過的節點,就是答案(不可以同時回溯)public class Main { static Map<String, String> sonFather; //son to father static Set<String> visited; public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = Integer.parseInt(in.nextLine()); sonFather = new HashMap<String, String>(); visited = new HashSet<String>(); for (int i = 0; i < n; i++) { String[] s = in.nextLine().split(" "); sonFather.put(s[1], s[0]); } int m = Integer.parseInt(in.nextLine()); for (int i = 0; i < m; i++) { String[] s = in.nextLine().split(" "); quest(s[0],s[1]); visited = new HashSet<String>(); } in.close(); } public static void quest(String s1, String s2) { if (s1.equals(s2)) { System.out.println(s1); return; } if (!sonFather.containsKey(s1) && !sonFather.containsKey(s2)) { System.out.println(-1); return; } while (sonFather.containsKey(s1)) { visited.add(s1); s1 = sonFather.get(s1); } visited.add(s1); while (sonFather.containsKey(s2) && !visited.contains(s2)) { s2 = sonFather.get(s2); } if (visited.contains(s2)) { System.out.println(s2); return; } System.out.println(-1); } }