【DFS/BFS】1466. 重新规划路径

【LeetCode】1466. 重新规划路线 Reorder Routes to Make All Paths Lead to the City Zero (Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录题目描述题目大意解题方法DFSBFS日期 题目地址:https://leetcode-cn.com/problems/reorder-routes-to-make-all-paths-lead-to-the-city-zero/ 题目描述 n 座城市,从 0 到 n-1 编号,其间共有 n-1 条路线。因此,要想在两座不同城市之间旅行只有唯一一条路线可供选择(路线网形成一颗. 阅读详情

题目描述

(中等)n 座城市,从 0 到 n-1 编号,其间共有 n-1 条路线。因此,要想在两座不同城市之间旅行只有唯一一条路线可供选择(路线网形成一颗树)。去年,交通运输部决定重新规划路线,以改变交通拥堵的状况。
路线用 connections 表示,其中 connections[i] = [a, b] 表示从城市 a 到 b 的一条有向路线。
今年,城市 0 将会举办一场大型比赛,很多游客都想前往城市 0 。
请你帮助重新规划路线方向,使每个城市都可以访问城市 0 。返回需要变更方向的最小路线数。
题目数据保证每个城市在重新规划路线方向后都能到达城市 0 。

示例:
示例图片

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

解题思路

最重要的是理解题意,尤其这种经过长篇幅文字包装的题,更要静下心来掌握题意!
容易分析得到以下结论:

  1. n个结点,n - 1条边且所有结点均能到达 ‘0’ 结点,即每个结点的出度(图论中的知识点)为1, ‘0’ 结点除外;
  2. 进一步分析,若将题目中的有向图视为无向图,则此图一定是以 ‘0’ 结点为根节点的树结构
  3. 重新规划路径方向,即结点间的连结关系不改,只改连接方向
  4. 最后,以 ‘0’ 结点为起点,依循连接关系遍历所有结点,对错误方向计数即可。

代码实现

先看深度优先(DFS):

class Solution {
public:
    int minReorder(int n, vector<vector<int>>& connections) {
    	//统计记录入度的邻接链表
        vector<vector<int>> in(n);
        //统计记录出度的邻接链表
        vector<vector<int>> out(n);
        //邻接链表初始化
        for(auto conn : connections){
            in[conn[1]].push_back(conn[0]);
            out[conn[0]].push_back(conn[1]);
        }
        //访问数组,避免边重复访问:对于一条边上的两个顶点,A是入边,B是出边。导致重复访问使结果大于正确值。
        vector<bool> visited(n, false);
        //初始化规划次数
        int ans = 0;
        //以‘0’结点为起点
        dfs(0, ans, in, out, visited);
        return ans;
    }
    
    //深度优先搜索
    void dfs(int node, int& ans, vector<vector<int>>& in, vector<vector<int>>& out, vector<bool>& visited){
    	//访问过的结点不进行下一步递归
        if(visited[node]) return;
        visited[node] = true;
        //遍历当前结点入边的弧头结点
        for(int i : in[node]){
            dfs(i, ans, in, out, visited);
        }
        //遍历当前结点入边的弧尾结点,此时必为错误方向,计数+ 1!!!
        for(int i : out[node]){
            if(!visited[i]) ans++;
            dfs(i, ans, in, out, visited);
        }
    }
};

运行结果:

运行结果

深度优先的另一种实现思路:

class Solution {
public:
    int minReorder(int n, vector<vector<int>>& connections) {
        //有向图邻接矩阵
        vector<vector<int>> withDire(n);
        //无向图邻接矩阵
        vector<vector<int>> withOutDire(n);
        for(auto conn : connections){
            withDire[conn[0]].push_back(conn[1]);
            withOutDire[conn[0]].push_back(conn[1]);
            withOutDire[conn[1]].push_back(conn[0]);
        }
        vector<bool> visited(n, false);
        int ans = 0;
        dfs(withDire, withOutDire, visited, 0, ans);
        return ans;
    }

    void dfs(vector<vector<int>>& withDire, vector<vector<int>> &withOutDire, vector<bool>& visited, int node, int& ans){
        if(visited[node]) return;
        visited[node] = true;
        for(int i : withOutDire[node]){
            if(visited[i]) continue;
            //无需分出、入度考虑,代码逻辑统一
            if(find(withDire[node].begin(), withDire[node].end(), i) != withDire[node].end()) ans++;
            dfs(withDire, withOutDire, visited, i, ans);
        }           
    }
};

再看广度优先(BFS):
通过建立边的索引目录,并且相较于上述DFS,以边为中心,极大减少了时间、内存开销。

class Solution {
public:
    int minReorder(int n, vector<vector<int>>& connections) {
        int ans = 0;
        //创建顶点--边的关系的索引
        vector<vector<int>> edgeIndex(n);
        //初始化索引
        for(int i = 0; i < connections.size(); i++){
            edgeIndex[connections[i][0]].push_back(i);
            edgeIndex[connections[i][1]].push_back(i);
        }
        //以边为核心,创建访问数组
        vector<bool> visited(n - 1);
        //广度优先
        queue<int> que;
        que.push(0);
        while(!que.empty()){
            int node = que.front();
            que.pop();
            for(int i : edgeIndex[node]){
            	//重复访问边,直接跳过当前循环
                if(visited[i]) continue;
                visited[i] = true;
                //当前结点为边的弧头,必为错误方向!
                if(node == connections[i][0]){
                    ans++;
                    que.push(connections[i][1]);
                }else{
                    que.push(connections[i][0]);
                }
            }
        }
        return ans;
    }
};

运行结果
广度优先的代码里,创建索引是亮点,也是性能提升的关键。避免了像深度优先开辟额外空间创建各种类型的邻接矩阵,且避免在递归中使用std::find()这种时间复杂度为O(n)的操作。

数学建模6——路径规划的各种算法(Dijkstra、Floyd、A*、D*、RRT*、LPA*) 简单的对路径规划的几种经典算法进行介绍,最后简述了一下各方法的区别 阅读详情

相关推荐

[运动规划算法]基于滚动优化的路径规划器lexicographic_planning

Tixiao Shan, Wei Wang, Brendan Englot, Carlo Ratti, Daniela Rus

xiewf的博客 3646

Grid-based Route Re-Planning/基于网格的路径重新规划问题

对于Grid-based Route Re-Planning 问题的求解

qq_62711060的博客 833

车辆模型预测控制局部轨迹重规划

无人车辆局部轨迹重规划,所有代码都详细提供了详尽的注解

1466. 重新规划路线

输入:n = 6, connections = [[0,1],[1,3],[2,3],[4,0],[4,5]]输入:n = 5, connections = [[1,0],[1,2],[3,2],[3,4]]这道题的描述有点问题,第一种情况,其实可以两次就解决,把0-1删掉,把3连到0上就行了。输入:n = 3, connections = [[1,0],[2,0]]解释:更改以红色显示的路线的方向,使每个城市都可以到达城市 0。解释:更改以红色显示的路线的方向,使每个城市都可以到达城市 0。

qigezuishuaide的博客 551

ROS move_base 自主重规划全局路径

ROS move_base 自主重规划全局路径

weixin_56867479的博客 2891

LeetCode 1466. 重新规划路线(DFS/BFS

文章目录1. 题目2. 解题2.1 DFS2.2 BFS 1. 题目 n 座城市,从 0 到 n-1 编号,其间共有 n-1 条路线。因此,要想在两座不同城市之间旅行只有唯一一条路线可供选择(路线网形成一颗树)。 去年,交通运输部决定重新规划路线,以改变交通拥堵的状况。 路线用 connections 表示,其中 connections[i] = [a, b] 表示从城市 a 到 b 的一条有向路线。 今年,城市 0 将会举办一场大型比赛,很多游客都想前往城市 0 。 请你帮助重新规划路线方向,使每个城市都

Michael是个半路程序员 2870

Leetcode 1466. 重新规划路线 正向+逆向DFS/BFS

【代码】Leetcode 1466. 重新规划路线 正向+逆向DFS/BFS

想买很多漂亮衣服但是买不起的博客 321

【LeetCode】每日一题 2023_12_7 重新规划路线(DFS/BFS

【LeetCode】每日一题 2023_12_7 重新规划路线(DFS/BFS

Locky136的博客 742

LeetCode 每日一题 Day 6(DFS+BFS)

n 座城市,从 0 到 n-1 编号,其间共有 n-1 条路线。因此,要想在两座不同城市之间旅行只有唯一一条路线可供选择(路线网形成一颗树)。去年,交通运输部决定重新规划路线,以改变交通拥堵的状况。路线用 connections 表示,其中 connections[i] = [a, b] 表示从城市 a 到 b 的一条有向路线。今年,城市 0 将会举办一场大型比赛,很多游客都想前往城市 0。请你帮助重新规划路线方向,使每个城市都可以访问城市 0。返回需要变更方向的最小路线数。

m0_73814009的博客 1666

基于Autoware分析op_global_planner全局路径规划模块重规划

基于Autoware分析op_global_planner全局路径规划模块重规划 本次带来的是Autoware中的路网路径规划op_global_planner的重规划问题,在实际应用中我们肯定不仅仅是单纯的从起点到终点的问题,可能需要很多中间点或者说到了终点又返回的问题,那么这就涉及到了重规划,op_global_planner提供了重规划的接口,叫错Replanning,可以在人机交互界面直接手动点击打开重规划功能: 然后介绍一下重规划功能的几个要注意的点: 在给定起始点和第一个目标点的时候,是可以生

weixin_44570248的博客 3070

关于路径规划问题的详细总结(千字长文)

本文详细介绍了现行的几类主流的路径规划算法,有实例解析,轻松易懂。

weixin_52241563的博客 9767

路径规划】原理及实现

路径规划(Path Planning)是指在给定地图、起始点和目标点的情况下,确定应该采取的最佳路径。常见的路径规划算法包括A* 算法、Dijkstra 算法、RRT(Rapidly-exploring Random Tree)等。

lly_csdn123的博客 1万+

路径规划算法

路径规划中,每⼀帧都规划,如果感知识别出来的障碍物bounding box不稳定,每⼀帧也会随着bounding box的改变⽽上下跳动,带来的问题就是⾏驶中的不稳定,路径根据障碍物上下跳动。所以Apollo引⼊路径重⽤决策,如果上⼀帧路径没和障碍物发⽣碰撞,这⼀帧路径直接复⽤上⼀帧路径,不会再进⾏接下来的路径规划,直接跳到速度规划的部分。根据路径对障碍物赋予决策,⽐如最后是向左绕⾏的路径,会对绕⾏障碍物进⾏决策,就产⽣⼀个停⽌的决策,这个决策主要是对速度规划使⽤。条件满⾜后会产⽣向左或者向右的决策。

m0_62664599的博客 2455

使用java写个路径规划算法

使用 Java 实现路径规划算法需要先了解基本的图论知识,以及常用的路径规划算法,如 Dijkstra 算法、A* 算法等。在进行代码实现之前,需要确定所使用的图存储结构,以及每一步如何使用算法进行计算。 具体实现步骤如下: 定义图存储结构,例如邻接矩阵或邻接表。 实现起点和终点的设置,并初始化每个点的距离值。 实现算法的核心部分,依据 Dijkstra 或 A* 算法的公式进行计算。 重...

weixin_42587866的博客 842

1466 重新规划路线(dfs、建立双向的路径

1. 问题描述: n 座城市,从 0 到 n-1 编号,其间共有 n-1 条路线。因此,要想在两座不同城市之间旅行只有唯一一条路线可供选择(路线网形成一颗树)。去年,交通运输部决定重新规划路线,以改变交通拥堵的状况。 路线用 connections 表示,其中 connections[i] = [a, b] 表示从城市 a 到 b 的一条有向路线。 今年,城市 0 将会举办一场大型比赛,很多游客都想前往城市 0 。 请你帮助重新规划路线方向,使每个城市都可以访问城市 0 。返回需要变更方向的最小路线

二哈 1125

路径规划算法总结

路径规划算法 1、Dijkstra算法 从物体所在的初始点开始,访问图中的结点。迭代检查 待检查节点集中的节点,该节点从初始节点向外扩展,直到达到目标节点,该算法能够保证找到一条从初始点到目标点的最短路径。 2.最佳优先搜索(BFS算法 按照类似的流程进行,不同的是它能够评估任意节点到目标节点的 代价 (距离大小)。它选择的不是离初始点最近的节点,而是离目标点最近的节点 。它用了一个启发式函数快速的导向目标节点。例如,如果目标位于出发点的南方,BFS将趋向于导向南方的路径。 如下所示;越黄的值代表越高

小蜗牛的珍贵百宝箱 1万+
上一篇: 【最短路径--BFS】1129. 颜色交替的最短路径
下一篇: 【并查集】547. 省份数量
LogosTR_
博客等级 码龄4年 362粉丝 · 52原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值