3244. 新增道路查询后的最短距离 II(并查集)

https://leetcode.cn/problems/shortest-distance-after-road-addition-queries-i/description/
这个题分两个版本,一个简单的,一个困难的。

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

n个城市,编号从0n1。初始时,每个城市i都有一条单向道路通往城市i+10<=i<n1
queries[i]=[ui,vi] 表示新建一条从城市ui到城市vi的单向道路。每次查询后,你需要找到从城市0到城市n1的最短路径的长度。
返回一个数组answer,对于范围[0,queries.length1]中的每个ianswer[i]是处理完前i+1个查询后,从城市0到城市n1的最短路径的长度。

示例 1:
输入: n = 5, queries = [[2, 4], [0, 2], [0, 4]]
输出: [3, 2, 1]
解释:
image
新增一条从 2 到 4 的道路后,从 0 到 4 的最短路径长度为 3。
image
新增一条从 0 到 2 的道路后,从 0 到 4 的最短路径长度为 2。
image
新增一条从 0 到 4 的道路后,从 0 到 4 的最短路径长度为 1。

示例 2:
输入: n = 4, queries = [[0, 3], [0, 2]]
输出: [1, 1]
解释:
image
新增一条从 0 到 3 的道路后,从 0 到 3 的最短路径长度为 1。
image
新增一条从 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]
查询中没有重复的道路。

这个是简单版本,直接最短路就行
bfs

class Solution {
typedef pair<int,int>PII; 
public:
	int dfs(int n,vector<vector<int>>& e){
		vector<int>vis(n,0);
		queue<PII>q;
		q.push({0,0});
		while(q.size()){
			PII top=q.front();
			int u=top.first;
			int st=top.second;
			q.pop();
			for(int i=0;i<e[u].size();i++){
				int v=e[u][i];
                if(!vis[v]){
                    if(v==n-1){
                        return st+1;
                    }
                    q.push({v,st+1});
                    vis[v]=1;
                }
			}
		}
		
		return -1;
	}
    vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries) {
        int m=queries.size();
        vector<vector<int>>e(n);
        for(int i=0;i<n-1;i++){
        	e[i].push_back(i+1);
		}
        vector<int>ans;
        for(int i=0;i<m;i++){
        	int u=queries[i][0];
        	int v=queries[i][1];
        	e[u].push_back(v);
            int res=dfs(n,e);
            ans.push_back(res);
        	//cout<<res<<endl;
		}
        return ans;
    }
};

spfa

class Solution {
public:
	int dfs(int n,vector<vector<int>>& e){
		vector<int>vis(n,0);
        vector<int>dis(n,0x3f3f3f3f);
        queue<int>q;
		q.push(0);
        dis[0]=0;
		while(q.size()){
			int u=q.front();
			q.pop();
            vis[u]=0;
			for(int i=0;i<e[u].size();i++){
				int v=e[u][i];
                if(dis[v]>dis[u]+1){
                    dis[v]=dis[u]+1;
                    if(!vis[v]){
                        vis[v]=1;
                        q.push(v);
                    }  
                }
			}
		}
		
		return dis[n-1];
	}
    vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries) {
        int m=queries.size();
        vector<vector<int>>e(n);
        for(int i=0;i<n-1;i++){
        	e[i].push_back(i+1);
		}
        vector<int>ans;
        for(int i=0;i<m;i++){
        	int u=queries[i][0];
        	int v=queries[i][1];
        	e[u].push_back(v);
            int res=dfs(n,e);
            ans.push_back(res);
        	//cout<<res<<endl;
		}
        return ans;
    }
};

困难难度:
https://leetcode.cn/problems/shortest-distance-after-road-addition-queries-ii/description/
3244. 新增道路查询后的最短距离 II
给你一个整数n和一个二维整数数组queries
n个城市,编号从0n1。初始时,每个城市i都有一条单向道路通往城市i+10<=i<n1
queries[i]=[ui,vi] 表示新建一条从城市ui到城市vi的单向道路。每次查询后,你需要找到从城市0到城市n1的最短路径的长度。
所有查询中不会存在两个查询都满足queries[i][0]<queries[j][0]<queries[i][1]<queries[j][1]

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

示例 1:
输入: n = 5, queries = [[2, 4], [0, 2], [0, 4]]
输出: [3, 2, 1]
解释:
image
新增一条从 2 到 4 的道路后,从 0 到 4 的最短路径长度为 3。
image
新增一条从 0 到 2 的道路后,从 0 到 4 的最短路径长度为 2。
image
新增一条从 0 到 4 的道路后,从 0 到 4 的最短路径长度为 1。

示例 2:
输入: n = 4, queries = [[0, 3], [0, 2]]
输出: [1, 1]
解释:
image
新增一条从 0 到 3 的道路后,从 0 到 3 的最短路径长度为 1。
image
新增一条从 0 到 2 的道路后,从 0 到 3 的最短路径长度仍为 1。

提示:
3<=n<=105
1<=queries.length<=105
queries[i].length == 2
0 <= queries[i][0] < queries[i][1] < n
1 < queries[i][1] - queries[i][0]
查询中不存在重复的道路。
不存在两个查询都满足 i != j 且 queries[i][0] < queries[j][0] < queries[i][1] < queries[j][1]。

第一直觉就是并查集
https://leetcode.cn/problems/shortest-distance-after-road-addition-queries-ii/solutions/2868463/bing-cha-ji-by-mipha-2022-p4qk/

class Solution {
public:
    int find(int x,vector<int> &p) {
        if (x != p[x]) {p[x] = find(p[x],p);}
        return p[x];
    }
    void merge(int x, int y, vector<int> &p, int &cnt) {
        int rx = find(x,p), ry = find(y,p);
        if (rx != ry) {
            p[rx] = ry;
            cnt--;
        }
    }
    vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries) {
        int cnt = n-1;
        vector<int> ans;
        vector<int> p(n-1);
        iota(p.begin(),p.end(),0);//将p变为[0,1,2,3...n-1] 
        for (int i = 0; i < queries.size(); ++i) {
            int l = queries[i][0], r = queries[i][1] - 1;//[0,2]
            int rl = find(l,p),rr = find(r,p);
            for (int i = rl; i < rr; i = find(i+1,p)) {
                merge(i,rr,p,cnt);
            }
            ans.push_back(cnt);
        }
        return ans;
    }
};


class Solution {
public:
    vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries) {
        vector<int> mp(n, 0), ans;
        for(int i = 0; i < n - 1; i++) mp[i] = i + 1;
        int t = n - 1;
        for(auto &q: queries) {
            if (mp[q[0]] < q[1]) {
                for(int i = mp[q[0]]; i < q[1]; i++) {
                    if (mp[i] != n) {
                        mp[i] = n;
                        t--;
                    }
                }
                mp[q[0]] = q[1];
            }
            ans.push_back(t);
        }
        return ans;
    }
};
posted @   lipu123  阅读(21)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示