力扣3243(bfs/dp)

方法一:广度优先搜索

前面说到,深度优先搜索是一条路径走到底再回溯。而广度优先搜索是先探索深度相同的所有节点,再拓展深度。如果在树中,就是层序遍历。

此题中,只需从0开始搜索与它直接相连的节点,更新距离。再进一步搜索与这些节点直接相连的节点,继续更新距离即可。

class Solution
{
public:
    int bfs(int n, const vector<vector<int>>& graph)
    {
        vector<int>dis(n, -1);//dis[i]表示节点0到节点i的最短距离
        queue<int>que;
        que.push(0);
        dis[0] = 0;
        while (!que.empty())
        {
            int x = que.front();
            que.pop();

            for (int t : graph[x])
            {
                if (dis[t] >= 0)//由于从0开始,所以如果dis[t]已经非负,意味着已经有最短路径了
                //举个例子:先连接0与3,再连接0与2。对与2直接相连的节点进行bfs时,会发现dis[3]已经非负了
                {
                    continue;
                }
                que.push(t);
                dis[t] = dis[x] + 1;
            }
        }
        return dis[n - 1];
    }
    vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries)
    {
        vector<vector<int>>graph(n);
        for (int i = 0; i < n - 1; i++)
        {
            graph[i].push_back(i + 1);
        }
        
        vector<int>res;
        for (auto& q : queries)
        {
            graph[q[0]].push_back(q[1]);
            res.push_back(bfs(n, graph));
        }
        return res;
    }
};

方法二:动态规划

class Solution 
{
public:
    vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries) 
    {
        vector<vector<int>>prev(n);//prev[i]中存储的节点都是可以直接到达节点i的
        vector<int>dis(n);//节点0到节点i的距离
        for (int i = 1; i < n; i++)
        {
            prev[i].push_back(i - 1);
            dis[i] = i;
        }
        vector<int>ans;
        for(auto&q:queries)
        {
            prev[q[1]].push_back(q[0]);
            for(int v=q[1];v<n;v++)
            //添加一条q[0]->q[1]的路径后,只有q[1]及其后面的节点到节点0的距离会改变
            {
                for(int u:prev[v])
                {
                    dis[v]=min(dis[v],dis[u]+1);
                }
            }
            ans.push_back(dis[n-1]);
        }
        return ans;
    }
};

模拟一下就很清晰了。假设是0->1->2->3->4->5.现在我们新建一条路2->4,那么从4开始往后的节点到节点0的最短路长度就会改变。从4开始:这时与4直接相连的节点有3,2.开始遍历这两个节点:当u=3,dis[3]+1=dis[4],不改变;当u=2,dis[2]+1=3<dis[4],更新dis[4]。接着到5:由于改变了dis[4],所以dis[5]也会发生改变。也就是说,这种改变是从前往后推的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值