2019校招美團程式設計-圖的遍歷(JAVA)
第一行為節點數n,其他為n-1條邊,判斷1號結點出發的最短路徑
輸入:
4
1 2
1 3
3 4
輸出:
4
解題思路:有的邊走兩遍,有的邊只走一遍(最大深度的邊只走一遍),所以最短路程 = 2*(n-1)-最大深度。
參考:
public class 圖的遍歷 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] m = new int[100005];
for (int i = 1; i < n; i++) {
int k = sc.nextInt();
int t = sc.nextInt();
m[t]=m[k]+1;//t的結點深度,並且預設t在k的下一層結點
}
int sum = 0;
for(int i=1;i<=n;i++){
sum = Math.max(sum, m[i]);
}
System.out.println(2*(n-1)-sum);
sc.close();
}
}
個人覺得這思路雖然巧妙,但是必須預設輸入的資料是從節點1往下的結構(如 1 2, 1 3, 3,4)。
4
1 2
1 3
3 4
結構如下:
1
2 3
4
輸出:2*3-2=4
但是,當輸入的資料是
4 4 3 3 1 2 1
結構如下:
4
3
1
2
輸出:2*3-1=5
所以,個人覺得還是深度搜索更嚴謹。
參考此連結
public class main2 {
static int ans = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] temp = new int[n + 1][n + 1];
HashMap<Integer, HashSet<Integer>> map = new HashMap<>();
// 建圖
for (int i = 1; i < n; i++) {
int k = sc.nextInt();
int v = sc.nextInt();
HashSet<Integer> value = map.getOrDefault(k, new HashSet<Integer>());
value.add(v);
map.put(k, value);
HashSet<Integer> key = map.getOrDefault(v, new HashSet<Integer>());
key.add(k);
map.put(v, key);
}
//參考別人演算法,新增資料到陣列
for (int j = 1; j <= n; j++) {
Iterator<Integer> it = map.get(j).iterator();
int count = 0;
while (it.hasNext()) {
temp[j][count] = it.next();
count++;
}
}
dfs(1, 0, 0, temp);
System.out.println(2 * n - 2 - ans);
}
private static void dfs(int x, int old, int w, int[][] temp) {
for (int i = 0; i < temp[x].length; i++) {
if (temp[x][i] == 0) {
break;
}
if (temp[x][i] == old) {
continue;
}
dfs(temp[x][i], x, w + 1, temp);
}
ans = Math.max(ans, w);
}
}