LeetCode:1466. 重新规划路线(DFS C++、Java)

2023-12-13 10:56:23

目录

1466. 重新规划路线

题目描述:

实现代码与解析:

DFS

原理思路:


1466. 重新规划路线

题目描述:

? ?n?座城市,从?0?到?n-1?编号,其间共有?n-1?条路线。因此,要想在两座不同城市之间旅行只有唯一一条路线可供选择(路线网形成一颗树)。去年,交通运输部决定重新规划路线,以改变交通拥堵的状况。

路线用?connections?表示,其中?connections[i] = [a, b]?表示从城市?a?到?b?的一条有向路线。

今年,城市 0 将会举办一场大型比赛,很多游客都想前往城市 0 。

请你帮助重新规划路线方向,使每个城市都可以访问城市 0 。返回需要变更方向的最小路线数。

题目数据?保证?每个城市在重新规划路线方向后都能到达城市 0 。

示例 1:

输入:n = 6, connections = [[0,1],[1,3],[2,3],[4,0],[4,5]]
输出:3
解释:更改以红色显示的路线的方向,使每个城市都可以到达城市 0 。

示例 2:

输入:n = 5, connections = [[1,0],[1,2],[3,2],[3,4]]
输出:2
解释:更改以红色显示的路线的方向,使每个城市都可以到达城市 0 。

示例 3:

输入:n = 3, connections = [[1,0],[2,0]]
输出:0

提示:

  • 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]

实现代码与解析:

DFS

C++

class Solution {
public:
    int N = 5 * 10000 +  10;
    vector<int> e = vector<int>(N * 2, 0), ne = vector<int>(N * 2, 0), h = vector<int>(N, -1), d = vector<int>(N * 2, 0);
    int idx = 0;
    int res = 0;
    void add(int a, int b) {
        e[idx] = b; ne[idx] = h[a]; h[a] = idx++;
    }

    void dfs(int cur, int p) {
        
        for (int i = h[cur]; ~i; i = ne[i]) {
            int j = e[i];
            if (j == p) continue;
            if (d[i] == 1) res++;
            dfs(j, cur);
        }
    }
    int minReorder(int n, vector<vector<int>>& connections) {

        for (auto t: connections) {
            d[idx] = 1; 
            add(t[0], t[1]);
            add(t[1], t[0]);
        }
        dfs(0, -1);
        return res;
    }
};

Java

class Solution {
    public int N = 5 * 10000 + 10;
    public int[] e = new int[N * 2], ne = new int[N * 2], h = new int[N], d = new int[N * 2];
    public int idx = 0;
    public int res = 0;
    void add(int a, int b) {
        e[idx] = b; ne[idx] = h[a]; h[a] = idx++;
    }

    void dfs(int cur, int p) {

        for (int i = h[cur]; i != -1; i = ne[i]) {
            int j = e[i];
            if (j == p) continue;
            if (d[i] == 1) res++;
            dfs(j, cur);
        }
    }
    public int minReorder(int n, int[][] connections) {

        Arrays.fill(h, -1);
        Arrays.fill(d, 0);
        for (int[] t: connections) {
            d[idx] = 1;
            add(t[0], t[1]);
            add(t[1], t[0]);
        }

        dfs(0, -1);
        return res;
    }
}

原理思路:

? ? ? ? 深度优先遍历,在存入边时,存入双向边,在d数组中记录真实是正向还是反向,然后从0开始dfs,遇到真实是正向边的,说明此边需要反转,res++。得到结果。

文章来源:https://blog.csdn.net/Cosmoshhhyyy/article/details/134849856
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。