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可以得到最短路径,反推一下就能得到题中需求值了。
- 创建n+1个节点,key为节点索引,val为达到给节点的最短时间(也通len长度)
- 维护一个队列,存储该当前节点索引和到达给节点所花费的时间。
- 计算等待时间(由于权值相等,所以len越长需要等待的时间越长)
小结
无权图最短路径问题,考虑BFS