Reorder Routes to Make All Paths Lead to the City Zero

There are n cities numbered from 0 to n-1 and n-1 roads such that there is only one way to travel between two different cities (this network form a tree). Last year, The ministry of transport decided to orient the roads in one direction because they are too narrow.

Roads are represented by connections where connections[i] = [a, b] represents a road from city a to b.

This year, there will be a big event in the capital (city 0), and many people want to travel to this city.

Your task consists of reorienting some roads such that each city can visit the city 0. Return the minimum number of edges changed.

It's guaranteed that each city can reach the city 0 after reorder.

Example 1:


Input: n = 6, connections = [[0,1],[1,3],[2,3],[4,0],[4,5]]
Output: 3
Explanation: Change the direction of edges show in red such that each node can reach the node 0 (capital).

Example 2:

 

Input: n = 5, connections = [[1,0],[1,2],[3,2],[3,4]]
Output: 2
Explanation: Change the direction of edges show in red such that each node can reach the node 0 (capital).

Example 3:

Input: n = 3, connections = [[1,0],[2,0]]
Output: 0

Constraints:

  • 2 <= n <= 5 * 10^4
  • connections.length == n-1
  • connections[i].length == 2
  • 0 <= connections[i][0], connections[i][1] <= n-1
  • connections[i][0] != connections[i][1]

思路:因爲題目是個tree,也就是隻有一條路徑,那麼從0出發,必須所有的點都是就是用BFS來做,如果neighobr 不是指向 parent,則需要改變;因爲要知道下一層的節點,而且又要知道指向關係,所以建立兩個圖即可;O(V + E),掃描一遍就可以了;

class Solution {
    public int minReorder(int n, int[][] connections) {
        HashMap<Integer, HashSet<Integer>> directGraph = new HashMap<>();
        HashMap<Integer, HashSet<Integer>> undirectGraph = new HashMap<>();
        
        for(int[] connect : connections) {
            // a -> b;
            int a = connect[0];
            int b = connect[1];
            
            undirectGraph.putIfAbsent(a, new HashSet<Integer>());
            undirectGraph.putIfAbsent(b, new HashSet<Integer>());
            undirectGraph.get(a).add(b);
            undirectGraph.get(b).add(a);
            
            // a -> b;
            directGraph.putIfAbsent(a, new HashSet<Integer>());
            directGraph.putIfAbsent(b, new HashSet<Integer>());
            directGraph.get(a).add(b);
        }
        
        boolean[] visited = new boolean[n];
        Queue<Integer> queue = new LinkedList<Integer>();
        queue.offer(0);
        visited[0] = true;
        
        int count = 0;
        while(!queue.isEmpty()) {
            int size = queue.size();
            for(int i = 0; i < size; i++) {
                Integer node = queue.poll();
                for(Integer neighbor: undirectGraph.get(node)) {
                    if(visited[neighbor]) {
                        continue;
                    }
                    if(!directGraph.get(neighbor).contains(node)) {
                        count++;
                    }
                    queue.offer(neighbor);
                    visited[neighbor] = true;
                }
            }
        }
        return count;
    }
}

思路:這題更牛逼的是:用set來解。因爲a - > b, 而且只有一條路通往兩個city;那麼分三種情況:

set 首先加入所有的點,然後所有可以到達0的點,全部remove掉;

1. 從0出去的,肯定要反過來;count++;

2. 從 a - > b, 如果a不在,代表a這個點是可以到達0的,那麼 a->b 必須反過來,count++;

3. 從a -> b, 如果b不在,代表a指向一個可以到達0的點,這條邊b 也可以到達0,那麼remove a,啥也不做,繼續scan;

O(N);

class Solution {
    public int minReorder(int n, int[][] connections) {
        HashSet<Integer> set = new HashSet<>();
        for(int i = 0; i < n; i++) {
            set.add(i);
        }
        set.remove(0);
        int count = 0;
        for(int[] connection: connections) {
            // a -> b;
            int a = connection[0];
            int b = connection[1];
            if(a == 0) {
                // 如果是從0出去的,必須反過來;
                count++;
                set.remove(b);
            } else if(!set.contains(a)) {
                // 如果從去掉的點裏面出發,那麼這個邊也必須反過來;
                count++;
                set.remove(b);
            } else if(!set.contains(b)) {
                // 如果指向的不在existing set裏面,代表指向的是一個指向0的father node;
                set.remove(a);
            } 
        }
        return count;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章