本题讲了一个故事,因为路窄,所以任意两城市间的路都改成了单行道(有向图)。
然后城市0要举办大型活动,需要所有城市都通向城市0,方便人们travel。
可以改变单行道的方向,使所有城市都能通向城市0,最少需要改变几条路。
思路:
直觉是从城市0出发,所有它能到达的路都需要改变方向(DFS)。
这样它能到达的城市才能反过来到达城市0.
但是看Example1, 0不能到达4,但是后面需要改变4到5的方向。
所以不能仅仅记正向的路,还要记反向的路。
这样还是从0出发,路过的所有正向的都需要改变方向,反向的不需要。
那么如何记下反向的路呢?
在建立有向图的时候,用(a,b)表示a到b的正向的路,用(a,-b)表示b到a的反向的路。
注意因为有-b的存在,所以DFS的时候要用到abs函数。
class Solution {
int reorder = 0;
boolean[] visited;
List<Integer>[] graph;
public int minReorder(int n, int[][] connections) {
graph = new ArrayList[n];
visited = new boolean[n];
//有向图,+表示a到b,-表示b到a
for(int i = 0; i < n; i++) graph[i] = new ArrayList<Integer>();
for(int[] conn : connections) {
graph[conn[0]].add(conn[1]);
graph[conn[1]].add(-conn[0]);
}
dfs(0);
return reorder;
}
void dfs(int city) {
visited[city] = true;
for(int nextCity : graph[city]) {
//visited判断要写在这里,因为涉及到reorder++,
//每个nextCity都需要立刻判断,而不是在dfs的开头判断
if(visited[Math.abs(nextCity)]) continue;
if(nextCity > 0) reorder ++;
dfs(Math.abs(nextCity)); //nextCity可能是负值,要用abs
}
}
}