给你一个整数 n
和一个二维整数数组 queries
。
有 n
个城市,编号从 0
到 n - 1
。初始时,每个城市 i
都有一条单向 道路通往城市 i + 1
( 0 <= i < n - 1
)。
queries[i] = [ui, vi]
表示新建一条从城市 ui
到城市 vi
的单向 道路。每次查询后,你需要找到从城市 0
到城市 n - 1
的最短路径 的长度。
返回一个数组 answer
,对于范围 [0, queries.length - 1]
中的每个 i
,answer[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;
}