首页 > 其他分享 >1786. 从第一个节点出发到最后一个节点的受限路径数 (Medium)

1786. 从第一个节点出发到最后一个节点的受限路径数 (Medium)

时间:2023-03-13 13:45:19浏览次数:47  
标签:Medium -- graph 路径 1786 vector vec 节点

问题描述

1786. 从第一个节点出发到最后一个节点的受限路径数 (Medium)

现有一个加权无向连通图。给你一个正整数 n ,表示图中有 n 个节点,并按从 1n
给节点编号;另给你一个数组 edges ,其中每个 edges[i] = [uᵢ, vᵢ, weightᵢ]
表示存在一条位于节点 uᵢvᵢ 之间的边,这条边的权重为 weightᵢ

从节点 start 出发到节点 end 的路径是一个形如 [z₀, z₁,z₂, ..., zₖ]
的节点序列,满足 z₀ = startzₖ = end 且在所有符合 0 <= i <= k-1
的节点 zᵢzᵢ+₁ 之间存在一条边。

路径的距离定义为这条路径上所有边的权重总和。用 distanceToLastNode(x) 表示节点 n
x 之间路径的最短距离。 受限路径 为满足 distanceToLastNode(zᵢ) > distanceToLastNode(zᵢ+₁) 的一条路径,其中 0 <= i <= k-1

返回从节点 1 出发到节点 n受限路径数 。由于数字可能很大,请返回对 10⁹ + 7
取余 的结果。

示例 1:

输入:n = 5, edges =
[[1,2,3],[1,3,3],[2,3,1],[1,4,2],[5,2,2],[3,5,1],[5,4,10]]
输出:3
解释:每个圆包含黑色的节点编号和蓝色的 distanceToLastNode 值。三条受限路径分别是:
1) 1 --> 2 --> 5
2) 1 --> 2 --> 3 --> 5
3) 1 --> 3 --> 5

示例 2:

输入:n = 7, edges =
[[1,3,1],[4,1,2],[7,3,4],[2,5,3],[5,6,1],[6,7,2],[7,5,3],[2,6,4]]
输出:1
解释:每个圆包含黑色的节点编号和蓝色的 distanceToLastNode 值。唯一一条受限路径是:1 --> 3
--> 7 。

提示:

  • 1 <= n <= 2 * 10⁴
  • n - 1 <= edges.length <= 4 * 10⁴
  • edges[i].length == 3
  • 1 <= uᵢ, vᵢ <= n
  • uᵢ != vᵢ
  • 1 <= weightᵢ <= 10⁵
  • 任意两个节点之间至多存在一条边
  • 任意两个节点之间至少存在一条路径

解题思路

首先利用Dijkstra算法来计算各点到点n的最短距离,建立邻接表的时候,要注意本题的图是无向图,所以应该是:

vector<vector<vector<int>>> graph(n + 1);
for (auto &vec : edges) {
    graph[vec[0]].push_back({vec[1], vec[2]});
    graph[vec[1]].push_back({vec[0], vec[2]});
}

得到各点到n的最短距离之后,即可采用记忆化搜索来解决,从点i到点n的路径数即与i相连且满足条件的点到n的路径数之和。

代码

class Solution {
  public:
    int mod = 1000000007;
    void Dijkstra(vector<vector<vector<int>>> &graph, int n, vector<int> &dis, vector<int> &is_min) {
        auto cmp = [&](pair<int, int> &p1, pair<int, int> &p2) {
            return p1.second > p2.second;
        };
        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> pq(cmp);
        pq.push({n, 0});
        while (!pq.empty()) {
            auto [idx, len] = pq.top(); // vec[0]表示坐标,vec[1]表示距离
            // cout << idx << " " << len << endl;
            pq.pop();
            if (is_min[idx] == 1) { // 说明已经找到最短路
                continue;
            }
            is_min[idx] = 1;
            dis[idx] = len;
            for (auto &tmp : graph[idx]) { // 遍历已经找到最短路的这个点的相邻边
                if (is_min[tmp[0]] == 0) {
                    pq.push({tmp[0], len + tmp[1]});
                }
            }
        }
    }
    int dfs(int idx, vector<vector<vector<int>>> &graph, int n, vector<int> &dis, vector<int> &is_min, vector<int> &cach) {
        if (idx == n) {
            return 1;
        }
        if (cach[idx] != -1) {
            return cach[idx];
        }
        int res = 0;
        for (auto &vec : graph[idx]) {
            if (is_min[idx] == 1 && dis[idx] > dis[vec[0]]) {
                res = (res + dfs(vec[0], graph, n, dis, is_min, cach)) % mod;
            }
        }
        cach[idx] = res;
        return cach[idx];
    }
    int countRestrictedPaths(int n, vector<vector<int>> &edges) {
        vector<vector<vector<int>>> graph(n + 1);
        for (auto &vec : edges) {
            graph[vec[0]].push_back({vec[1], vec[2]});
            graph[vec[1]].push_back({vec[0], vec[2]});
        }
        vector<int> dis(n + 1);
        vector<int> is_min(n + 1);
        vector<int> cach(n + 1, -1);
        Dijkstra(graph, n, dis, is_min); // 找到最短路径
        return dfs(1, graph, n, dis, is_min, cach);
    }
};

标签:Medium,--,graph,路径,1786,vector,vec,节点
From: https://www.cnblogs.com/zwyyy456/p/17211060.html

相关文章

  • 二叉树的下一个节点
    /***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNode*left;*TreeNode*right;*TreeNode*father;*T......
  • 743. 网络延迟时间 (Medium)
    问题描述743.网络延迟时间(Medium)有n个网络节点,标记为1到n。给你一个列表times,表示信号经过有向边的传递时间。times[i]=(uᵢ,vᵢ,wᵢ),其中uᵢ是源节......
  • 双节点部署方案
    背景:为了降低每个同学发版造成整个测试环境不可用,我们准备在saas药店业务线试点双节点部署为了有机器资源部署从节点,运维会回收test2环境双节点介绍:每个服务有主节点,从......
  • postgresql 递归查询,查询父子节点关联关系
    postgresql递归查询,查询父子节点关联关系CREATETABLE"public"."sys_department"("id"int4NOTNULLDEFAULTnextval('sys_department_id_seq'::regclass),"na......
  • Leetcode24. 两两交换链表中的节点
    题目描述:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 思路:使用虚拟头结点,这样会......
  • EasyUI的combotree 默认节点选中呢
    $('#selShenqFuwujg').combotree({url:'../../GetFuwujgInfo.aspx?type=GetFuwujgTree&PID=',onLoadSuccess:function(node,data){......
  • 1310. 子数组异或查询 (Medium)
    问题描述1310.子数组异或查询(Medium)有一个正整数数组arr,现给你一个对应的查询数组queries,其中queries[i]=[Lᵢ,Rᵢ]。对于每个查询i,请你计算从Lᵢ到Rᵢ......
  • LabVIEW|知识点:值属性节点、局部变量、数据连线三种方式的传递效率
    这是类似的线程切换导致效率低下的问题,出现在调用动态链接库的情况下,也出现在使用属性节点和方法节点时。比如,设置一个控件的值有三种常用方法。对于显示控件而言,可以直接通......
  • 剑指 Offer 18.删除链表节点
    题目表述   解法双指针法classSolution{public:ListNode*deleteNode(ListNode*head,intval){ListNode*a=head->next;......
  • 力扣中116 填充每个节点的下一个右侧节点指针
    题解1:  也就是一下就把队列里所有的元素移除了移除的同时添加左右节点队列中每次放的都是一层 题解2:找到next可以利用next找下一节点用pre标记每层第一个tmp......