leetcode 3243. 新增道路查询后的最短距离 I

给你一个整数 n 和一个二维整数数组 queries

n 个城市,编号从 0n - 1。初始时,每个城市 i 都有一条单向 道路通往城市 i + 10 <= i < n - 1)。

queries[i] = [ui, vi] 表示新建一条从城市 ui 到城市 vi单向 道路。每次查询后,你需要找到从城市 0 到城市 n - 1最短路径长度

返回一个数组 answer,对于范围 [0, queries.length - 1] 中的每个 ianswer[i] 是处理完 i + 1 个查询后,从城市 0 到城市 n - 1 的最短路径的长度

示例 1:

输入: n = 5, queries = \[2, 4, 0, 2, 0, 4]

输出: 3, 2, 1

解释:

新增一条从 2 到 4 的道路后,从 0 到 4 的最短路径长度为 3。

新增一条从 0 到 2 的道路后,从 0 到 4 的最短路径长度为 2。

新增一条从 0 到 4 的道路后,从 0 到 4 的最短路径长度为 1。

示例 2:

输入: n = 4, queries = \[0, 3, 0, 2]

输出: 1, 1

解释:

新增一条从 0 到 3 的道路后,从 0 到 3 的最短路径长度为 1。

新增一条从 0 到 2 的道路后,从 0 到 3 的最短路径长度仍为 1。

提示:

  • 3 <= n <= 500
  • 1 <= queries.length <= 500
  • queries[i].length == 2
  • 0 <= queries[i][0] < queries[i][1] < n
  • 1 < queries[i][1] - queries[i][0]
  • 查询中没有重复的道路。

分析:广度优先搜索(dfs)。由于每次查询都从0点出发,终点都为n,对于每次能到达的点i,先判断是否已经到过(可能由于添加了路径,导致提前到达),若没有到过,则将其入栈。每次更新栈的时候,ans的值需要增加1。直到最后一个点被访问到(可能栈里还有若干个点,但是已经不重要了),此时存储ans并退出dfs即可。

cpp 复制代码
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* shortestDistanceAfterQueries(int n, int** queries, int queriesSize, int* queriesColSize, int* returnSize) {
    int *ans=(int*)malloc(sizeof(int)*queriesSize);
    *returnSize=queriesSize;
    memset(ans,0,sizeof(int)*queriesSize);
    int ans_index=0;

    int path[501][501]={0};//这里我用了一个数组存储每个点存在的边
    for(int i=0;i<n;++i)
        path[i][0]=1,path[i][path[i][0]]=i+1;//每个数组的0号存储有多少条边,1号位开始存终点
    for(int i=0;i<queriesSize;++i)//注意所有边权值均为1
    {
        int start=queries[i][0],end=queries[i][1];//每次查询先将边存储到邻接表里
        path[start][0]++,path[start][path[start][0]]=end;
        
        int stack[550]={0},node[550]={0},t,l=0,r=1,temp_ans=0;
        t=1,stack[0]=0,node[0]=1;
        while(l<r&&node[n]!=1)
        {
            int ll=l,rr=r,f=0;
/*
            printf("r=%d l=%d ll=%d rr=%d stack=",r,l,ll,rr);
            for(int j=ll;j<rr;++j)
            {
                printf("%d ",stack[j]);
            }printf("\n");
*/
            for(int j=ll;j<rr;++j)
            {
                int tempnode=stack[j];
                for(int k=1;k<=path[tempnode][0];++k)
                {
                    if(!node[path[tempnode][k]])
                    {
                        if(path[tempnode][k]==n)//注意到达终点就可以退出dfs了
                        {
                            ans[ans_index++]=temp_ans;f=1;break;
                        }
                        node[path[tempnode][k]]=1,stack[r++]=path[tempnode][k];
                    }
                }
                if(f)break;
            }
            if(f)break;
            l=rr;temp_ans++;
        }
        //printf("\n");
    }

    return ans;
}
相关推荐
alphaTao15 小时前
LeetCode 每日一题 2026/8/24-2026/8/30
python·算法·leetcode
CoderYanger1 天前
A.每日一题:输入单词需要的最少按键次数 Ⅰ+Ⅱ
java·数据结构·算法·leetcode·面试
Navigator_Z1 天前
LeetCode //C - 1221. Split a String in Balanced Strings
c语言·算法·leetcode
玄昌盛不会编程2 天前
LeetCode——2091. 从数组中移除最大值和最小值
java·算法·leetcode
旖旎夜光2 天前
LeetCode 238:除自身以外数组的乘积(前缀和) —— 题解
数据结构·c++·算法·leetcode·前缀和
学习星球2 天前
单调栈——从“找下一个更大的“到柱状图中的最大矩形
数据库·c++·算法·leetcode·xcode
血小板要健康2 天前
网格 dfs 与 FloodFill:从岛屿、区域到搜索路径
笔记·算法·leetcode·深度优先
鹿角片ljp2 天前
LeetCode 141. 环形链表|从 HashSet 到快慢指针 O (1) 空间最优解
算法·leetcode·链表
ZC跨境爬虫3 天前
LeetCode 219. 存在重复元素 II(滑动窗口 + 哈希表详解)
算法·leetcode·散列表
Navigator_Z3 天前
LeetCode //C - 1220. Count Vowels Permutation
c语言·算法·leetcode