【leetcode_2045】【困难】second-minimum-time-to-reach-destination / 到达目的地的第二短时间

URL

链接:https://leetcode-cn.com/problems/second-minimum-time-to-reach-destination/


题目

[截图]
在这里插入图片描述
在这里插入图片描述


分析

[截图]


源码

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  //#include <assert.h>
  #include <limits.h>

  #define DEBUG

  struct Node {
      int val;
      struct Node *next;
  };

  struct Node *lst_alloc(){
      struct Node * ret = (struct Node *)malloc(sizeof(struct Node));
      memset(ret , 0 ,sizeof(struct Node));
      return ret;
  }

  void lst_free(struct Node *lst){
      while(lst != NULL){
          struct Node *tmp = lst->next;
          free(lst);
          lst = tmp;
      }
  }

  void lst_push_front(struct Node **plst , int val){
      struct Node *node = lst_alloc();
      node->val = val;
      node->next = *plst;
      *plst = node;
  }

  struct Pair{
      int node ;
      int len ;
  };

  //int secondMinimum(int n , int ** edges , int edges_size , int * edge_col_size , int time , int change){
  int secondMinimum(int n , int ** edges , int edges_size , int time , int change){
  #ifdef DEBUG
      printf("\n=> func : \n");
      printf("edges = ");
      for(int i = 0;i<n;++i){
          printf("{%d,%d} \t",edges[i][0],edges[i][1]);
      }
      printf("\nn = %d\n",n);
      printf("time = %d\n",time);
      printf("change = %d\n",change);
  #endif
      /* graph */
      struct Node **graph =(struct Node **)malloc((n+1)*sizeof(struct Node *));
      memset(graph , 0 ,(n+1)*sizeof(struct Node *));
      for (int i = 0; i < edges_size ; ++i) {
          lst_push_front(&graph[edges[i][0]],edges[i][1]);
          lst_push_front(&graph[edges[i][1]],edges[i][0]);
      }

      int *path = (int *)malloc((2 * n + 1) * sizeof(int));
      for (int i = 1; i <= n; i++) {
          path[i] =  INT_MAX;
          path[i + n] = INT_MAX;
      }

      /* queue , front , back */
      struct Pair *queue = (struct Pair *)malloc((2 * n + 1) * sizeof(struct Pair));
      int front = 0, back = 0;

      path[1] = 0;
      queue[back].node = 1;
      queue[back++].len = 0;

      while(path[n + n] == INT_MAX){
          int cur = queue[front].node;
          int len = queue[front++].len;
          struct Node *next = graph[cur];
          while(next){
              if (len + 1 < path[next->val]) {
                  path[next->val] = len + 1;
                  queue[back].node = next->val;
                  queue[back++].len = len + 1;
              } else if (len + 1 > path[next->val] && len + 1 < path[next->val + n]) {
                  path[next->val + n] = len + 1;
                  queue[back].node = next->val;
                  queue[back++].len = len + 1;
              }
              next = next->next;
          }
      }

      int ret = 0;
      for (int i = 0; i < path[n + n]; i++) {
          if (ret % (2 * change) >= change) {
              ret = ret + 2 * change - ret % (2 *change);
          }
          ret = ret + time;
      }

      free(queue);
      free(path);
      for (int i = 1; i <= n; i++) {
          lst_free(graph[i]);
      }
      free(graph);

      return ret;
  }

  int main()
  {
      int n = 5;
      int time = 3;
      int change = 5;

      int row = 5, col = 2;
      /* ori arr */
      int arr_edges[][2] = {{1,2},{1,3},{1,4},{3,4},{4,5}};
      /* 1.1 def int** */
      int ** edges = (int **)malloc(sizeof(int *) * row);
      /* 1.2 def int* */
      for(int i = 0;i < row; ++i){
          edges[i] = (int *)malloc(sizeof(int) * col);
      }
      /* 2. init int* */
      for(int i = 0;i<row ;++i){
          for(int j = 0 ; j<col ;++j){
              edges[i][j] = arr_edges[i][j];
          }
      }
  #ifdef DEBUG
      /* debug */
      printf("=> before : \n");
      printf("edges = ");
      for(int i = 0;i<row;++i){
          printf("{%d,%d} \t",edges[i][0],edges[i][1]);
      }
      printf("\nn = %d\n",n);
      printf("time = %d\n",time);
      printf("change = %d\n",change);
  #endif

      //int ret = secondMinimum(n,edges,5,NULL,time,change);
      int ret = secondMinimum(n,edges,5,time,change);
      printf("\n=> after : \n");
      printf("ret = '%d' (eq 13 ?)\n",ret);

      /* 3. free int* */
      for(int i = 0;i<row;++i){
          free(edges[i]);
      }

      return 0;
  }

=> before :
edges = {1,2}   {1,3}   {1,4}   {3,4}   {4,5}
n = 5
time = 3
change = 5

=> func :
edges = {1,2}   {1,3}   {1,4}   {3,4}   {4,5}
n = 5
time = 3
change = 5

=> after :
ret = '13' (eq 13 ?)


源码概述

官方给出的是BFS解法,求最短路径和严格次短路径得到题中计算值。
给出一个双向连通图,且权值相等,导致越长的路径要等待的时间越久,使用BFS可以得到最短路径,反推一下就能得到题中需求值了。

  1. 创建n+1个节点,key为节点索引,val为达到给节点的最短时间(也通len长度)
  2. 维护一个队列,存储该当前节点索引和到达给节点所花费的时间。
  3. 计算等待时间(由于权值相等,所以len越长需要等待的时间越长)

小结

无权图最短路径问题,考虑BFS

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

过得精彩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值