当前位置:   article > 正文

1724. 检查边长度限制的路径是否存在 II 并查集_力扣1724

力扣1724

1724. 检查边长度限制的路径是否存在 II

一张有 n 个节点的无向图以边的列表 edgeList 的形式定义,其中 edgeList[i] = [ui, vi, disi] 表示一条连接 ui 和 vi ,距离为 disi 的边。注意,同一对节点间可能有多条边,且该图可能不是连通的。

实现 DistanceLimitedPathsExist 类:

  • DistanceLimitedPathsExist(int n, int[][] edgeList) 以给定的无向图初始化对象。
  • boolean query(int p, int q, int limit) 当存在一条从 p 到 q 的路径,且路径中每条边的距离都严格小于 limit 时,返回 true ,否则返回 false 。

示例 1:

输入:
["DistanceLimitedPathsExist", "query", "query", "query", "query"]
[[6, [[0, 2, 4], [0, 3, 2], [1, 2, 3], [2, 3, 1], [4, 5, 5]]], [2, 3, 2], [1, 3, 3], [2, 0, 3], [0, 5, 6]]
输出:
[null, true, false, true, false]

解释:
DistanceLimitedPathsExist distanceLimitedPathsExist = new DistanceLimitedPathsExist(6, [[0, 2, 4], [0, 3, 2], [1, 2, 3], [2, 3, 1], [4, 5, 5]]);
distanceLimitedPathsExist.query(2, 3, 2); // 返回 true。存在一条从 2 到 3 ,距离为 1 的边,
                                          // 这条边的距离小于 2。
distanceLimitedPathsExist.query(1, 3, 3); // 返回 false。从 1 到 3 之间不存在每条边的距离都
                                          // 严格小于 3 的路径。
distanceLimitedPathsExist.query(2, 0, 3); // 返回 true。存在一条从 2 到 0 的路径,使得每条边的
                                          // 距离 < 3:从 2 到 3 到 0 行进即可。
distanceLimitedPathsExist.query(0, 5, 6); // 返回 false。从 0 到 5 之间不存在路径。

提示:

  • 2 <= n <= 1e4
  • 0 <= edgeList.length <= 1e4
  • edgeList[i].length == 3
  • 0 <= ui, vi, p, q <= n-1
  • ui != vi
  • p != q
  • 1 <= disi, limit <= 1e9
  • 最多调用 1e4 次 query 。

 来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/checking-existence-of-edge-length-limited-paths-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

做题结果

 成功,开始写了两种,在线和离线,然后发现有人提到快照,按照快照又写了一遍

方法1:在线

简单的说就是一次一个并查集。才1e4随便玩,每次重开一个并查集即可。

1.按边权排序

2. 每次查询重置并查集,然后把边权小于目标的进行链接

3. 并查集判断是否有连起来

  1. class DistanceLimitedPathsExist {
  2. int[] parent;
  3. int[] size;
  4. int n;
  5. int[][] edgeList;
  6. public DistanceLimitedPathsExist(int n, int[][] edgeList) {
  7. Arrays.sort(edgeList,(a,b)->a[2]-b[2]);
  8. parent = new int[n];
  9. size = new int[n];
  10. this.n = n;
  11. this.edgeList = edgeList;
  12. }
  13. private int root(int a){
  14. return parent[a]==a?a:root(parent[a]);
  15. }
  16. private void connect(int a, int b){
  17. int ra = root(a);
  18. int rb = root(b);
  19. if(ra==rb) return;
  20. if(size[ra]>size[rb]){
  21. size[ra]+=size[rb];
  22. parent[rb] = ra;
  23. }else{
  24. size[rb]+=size[ra];
  25. parent[ra] = rb;
  26. }
  27. }
  28. public boolean query(int p, int q, int limit) {
  29. for(int i = 0; i < n; i++){
  30. parent[i] = i;
  31. size[i] = 1;
  32. }
  33. for(int i = 0;i < edgeList.length && edgeList[i][2]<limit; i++){
  34. connect(edgeList[i][0],edgeList[i][1]);
  35. }
  36. return root(p)==root(q);
  37. }
  38. }

方法2:离线

我们也可以把所有结果提前算出来,放起来,需要的时候取出即可。每个边权都放一个并查集的parent. 这样就不用每次重置并查集了。

  1. class DistanceLimitedPathsExist {
  2. int[] parent;
  3. int[] size;
  4. int n;
  5. int[][] edgeList;
  6. TreeMap<Integer,int[]> map;
  7. public DistanceLimitedPathsExist(int n, int[][] edgeList) {
  8. Arrays.sort(edgeList,(a,b)->a[2]-b[2]);
  9. parent = new int[n];
  10. size = new int[n];
  11. this.n = n;
  12. this.edgeList = edgeList;
  13. map = new TreeMap<>();
  14. for(int i = 0; i < n; i++){
  15. parent[i] = i;
  16. size[i] = 1;
  17. }
  18. map.put(0,Arrays.copyOf(parent,n));
  19. for(int [] edge:edgeList){
  20. int a = edge[0];
  21. int b = edge[1];
  22. int v = edge[2];
  23. connect(a,b);
  24. map.put(v,Arrays.copyOf(parent,n));
  25. }
  26. }
  27. private int root(int a){
  28. return parent[a]==a?a:root(parent[a]);
  29. }
  30. private void connect(int a, int b){
  31. int ra = root(a);
  32. int rb = root(b);
  33. if(ra==rb) return;
  34. if(size[ra]>size[rb]){
  35. size[ra]+=size[rb];
  36. parent[rb] = ra;
  37. }else{
  38. size[rb]+=size[ra];
  39. parent[ra] = rb;
  40. }
  41. }
  42. public boolean query(int p, int q, int limit) {
  43. this.parent = map.get(map.floorKey(limit-1));
  44. return root(p)==root(q);
  45. }
  46. }

方法3:快照

方法2是很不错,但是很占空间。如果并查集不优化,其实一次只会改变一个点。对同一版本进行较少次数修改,可以使用快照进行优化。

  1. class DistanceLimitedPathsExist {
  2. SnapshotArray parent;
  3. public DistanceLimitedPathsExist(int n, int[][] edgeList) {
  4. Arrays.sort(edgeList,(a,b)->a[2]-b[2]);
  5. parent = new SnapshotArray(n);
  6. for(int i = 0; i < n; i++){
  7. parent.set(i,i,0);
  8. }
  9. for(int [] edge:edgeList){
  10. int a = edge[0];
  11. int b = edge[1];
  12. int v = edge[2];
  13. connect(a,b,v);
  14. }
  15. }
  16. private int root(int a,int v){
  17. return parent.get(a,v)==a?a:root(parent.get(a,v),v);
  18. }
  19. private void connect(int a, int b,int v){
  20. int ra = root(a,v);
  21. int rb = root(b,v);
  22. if(ra==rb) return;
  23. parent.set(rb,ra,v);
  24. }
  25. public boolean query(int p, int q, int limit) {
  26. return root(p,limit-1)==root(q,limit-1);
  27. }
  28. class SnapshotArray {
  29. Map<Integer,TreeMap<Integer,Integer>> indexVersion = new HashMap<>();
  30. int len = 0;
  31. public SnapshotArray(int length) {
  32. len = length;
  33. }
  34. public void set(int index, int val,int edition) {
  35. indexVersion.putIfAbsent(index,new TreeMap<>());
  36. indexVersion.get(index).put(edition,val);
  37. }
  38. public int get(int index, int snap_id) {
  39. TreeMap<Integer,Integer> map = indexVersion.getOrDefault(index,new TreeMap<>());
  40. return map.getOrDefault(map.floorKey(snap_id)==null?-1:map.floorKey(snap_id),0);
  41. }
  42. }
  43. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/131005
推荐阅读
相关标签
  

闽ICP备14008679号