zoukankan      html  css  js  c++  java
  • 882. Reachable Nodes In Subdivided Graph

    问题:

    给定一个无向图,n个节点

    每条边可分为0个or多个node,

    求从节点0开始,走maxMoves步,总共能经过多少个node。

    Example 1:
    Input: edges = [[0,1,10],[0,2,1],[1,2,2]], maxMoves = 6, n = 3
    Output: 13
    Explanation: The edge subdivisions are shown in the image above.
    The nodes that are reachable are highlighted in yellow.
    
    Example 2:
    Input: edges = [[0,1,4],[1,2,6],[0,2,8],[1,3,1]], maxMoves = 10, n = 4
    Output: 23
    
    Example 3:
    Input: edges = [[1,2,4],[1,4,5],[1,3,1],[2,3,4],[3,4,5]], maxMoves = 17, n = 5
    Output: 1
    Explanation: Node 0 is disconnected from the rest of the graph, so only node 0 is reachable.
     
    Constraints:
    0 <= edges.length <= min(n * (n - 1) / 2, 104)
    edges[i].length == 3
    0 <= ui < vi < n
    There are no multiple edges in the graph.
    0 <= cnti <= 104
    0 <= maxMoves <= 109
    1 <= n <= 3000
    

      

    example 1:

    解法:Dijkstra 最小路径

    思路:

    • 对于本题,题意:要求最多能经过多少点。
      • 可转化为:
      • 求0节点到各个节点的最短距离 + 到达每个节点后剩余的步数。
      • 因为:求到各个节点到【最短】距离,那么可以尽可能多的走到节点 + 且使得其剩余的步数更多。
    • 使用dis数组记录,到达每个节点剩余的步数。
      • 那么,遍历所有的边,对每条边:剩余步数★:
      • 所求为:min{ 两个节点剩余步数之和, 两节点间的距离 }
      • (去除重复计算的中间节点)
    • 最终结果res 
      • 能到达的各个节点数:dis.size
      • + 各条边的 剩余步数★。

    要求dis[](0到各个节点的剩余步数):Dijkstra

    • 使用优先队列,优先pop剩余步数更大的(也就是到达节点cost最小的)
      • 大->小:less
    • 每次pop一个节点,对该节点进行处理:
      • 如果该节点已经记录过dis,那么跳过
      • 否则,记录该节点dis
        • 然后再展开该节点,看下一个节点next:
          • 若dis[next]记录过,那么跳过。
        • 下一个节点:leftmoves= cur.leftmoves-cur_next_cost - 1(节点自己)
          • 若leftmoves<0那么无法到达next,跳过。
        • 其他记录next到queue。

    ⚠️ 注意:Dijkstra算法中,每pop处理一个节点再进行dis记录。

    防止在同层入队排序,就阻止了更小的节点记录。

    代码参考:

     1 class Solution {
     2 public://Dijkstra:shortest route to every node
     3     //->to get more [left moves] after arrived node.
     4     
     5     //conclusion: for every edge, which one of two node has left moves.
     6     //res = add{all these left moves} + Count(every reachable node(leftmoves>0)).
     7     
     8     //if both two nodes have left moves and these 2 moves duplicated in the middle.
     9     // we just need the all moves between this two nodes. cnti[node1][node2]
    10     // namely: min(leftmoves[node1]+leftmoves[node2], cnti[node1][node2])
    11     typedef pair<int,int> pii;
    12     int reachableNodes(vector<vector<int>>& edges, int maxMoves, int n) {
    13         int res = 0;
    14         priority_queue<pii,vector<pii>,less<pii>> q;//leftmoves, nodeid
    15         //less: first to pop the max value.
    16         //greater: first to pop the min value.
    17         //we need to pop max left, as to say the cost is min.
    18         unordered_map<int, int> dis;//nodeid, leftmoves;
    19         //undirected map->save both two node.
    20         vector<unordered_map<int, int>> graph(n);
    21         //graph[i]:{{node j1, moves1}{node j2, move2}...}
    22         for(auto e:edges) {
    23             graph[e[0]][e[1]]=e[2];
    24             graph[e[1]][e[0]]=e[2];
    25         }
    26         //base:
    27         q.push({maxMoves, 0});
    28         //dis[0] = maxMoves;
    29         pii cur;
    30         while(!q.empty()) {
    31             cur = q.top();
    32             q.pop();
    33             if(dis.count(cur.second)) continue;
    34             dis[cur.second] = cur.first;
    35             cout<<"node:"<<cur.second<<" leftmove:"<<dis[cur.second]<<endl;
    36             for(auto nextn:graph[cur.second]) {
    37                 int leftmoves = cur.first-nextn.second-1;
    38                 if(dis.count(nextn.first) || leftmoves<0) continue;
    39                 q.push({leftmoves, nextn.first});
    40                 //dis[nextn.first] = leftmoves;
    41             }
    42         }
    43         
    44         res = dis.size();
    45         for(auto e:edges) {
    46             int node1 = dis.count(e[0])?dis[e[0]]:0;
    47             int node2 = dis.count(e[1])?dis[e[1]]:0;
    48             res += min(node1+node2, e[2]);
    49         }
    50         return res;
    51     }
    52 };
  • 相关阅读:
    nginx能访问html静态文件但无法访问php文件
    LeetCode "498. Diagonal Traverse"
    LeetCode "Teemo Attacking"
    LeetCode "501. Find Mode in Binary Search Tree"
    LeetCode "483. Smallest Good Base" !!
    LeetCode "467. Unique Substrings in Wraparound String" !!
    LeetCode "437. Path Sum III"
    LeetCode "454. 4Sum II"
    LeetCode "445. Add Two Numbers II"
    LeetCode "486. Predict the Winner" !!
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14504952.html
Copyright © 2011-2022 走看看