简体   繁体   English

检查是否可以到达相互链接的两点列表之间的所有点的算法

[英]Algorithm to check whether all points between a list of two points linked to each other can be reached

Given several pairs of points, I am trying to figure out a way to determine if all points can be reached from each other.给定几对点,我试图找出一种方法来确定是否可以相互到达所有点。

For example, given these undirected paths between points [1,6] :例如,给定点[1,6]之间的这些无向路径:

1 - 4
4 - 5
2 - 6
2 - 4
5 - 2

I can see that all points can be reached from each other.我可以看到所有的点都可以相互到达。

However, for something like:但是,对于类似的东西:

5 - 2
0 - 5
6 - 7

Points 6 and 7 cannot be reached from 0, 5, and 2.不能从 0、5 和 2 到达点 6 和 7。

I've tried a lot to play around with HashMap s and other ways to store the data but I can't seem to figure out a way to verify it all.我已经尝试了很多HashMap s 和其他存储数据的方法,但我似乎无法找到一种方法来验证这一切。 Especially given points like 1 in the first example where there is only one instance of it.特别是在第一个例子中给出像 1 这样只有一个实例的点。

I've been able to check whether there is a path between 2 given points:我已经能够检查 2 个给定点之间是否存在路径:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class GondolaLiftsOne {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int n = in.nextInt(), start = in.nextInt(), destination = in.nextInt(), count = 0, entries = 0;
        HashMap<Integer, ArrayList<Integer>> paths = new HashMap<>();

        for (int i = 0; i < n; i++) {
            int key = in.nextInt();
            if (!paths.containsKey(key)) paths.put(key, new ArrayList<>());

            entries++;
            paths.get(key).add(in.nextInt());
        }

        while (destination != start) {
            if (count > entries*2) {
                System.out.println("No, but you can walk!");
                return;
            }
            destination = getPath(paths, destination);
            count++;
        }
        System.out.println("YESSIREE");
    }

    public static int getPath (HashMap<Integer, ArrayList<Integer>> paths, int destination) {
        for (Map.Entry<Integer, ArrayList<Integer>> entry : paths.entrySet()) {
            for (int value : entry.getValue()) {
                if (value == destination) return entry.getKey();
            }
        }
        return -1;
    }
}

But otherwise, I have a hard time figuring out whether all points are connected.但除此之外,我很难弄清楚是否所有点都已连接。 I can't seem to find any similar questions like this online.我似乎无法在网上找到任何类似的问题。

This is basically simple BFS for an undirected graph.这基本上是无向图的简单BFS

  1. Create an adjacency list创建邻接表
  2. If you have any vertex with in-degree 0, return False如果有任何入度为 0 的顶点,则返回False
  3. Pick up any node and start BFS from it by queueing its neighbours and maintaining a visited list拿起任何节点并通过排队其邻居并维护visited列表从它开始 BFS

In the end, if all vertices are marked true , you know all points can be reached.最后,如果所有顶点都标记为true ,您就知道可以到达所有点。

Here is one algorithm you can use.这是您可以使用的一种算法。 No idea whether or not there's a better one.不知道是否有更好的。

Maintain a set of sets of points, where each of the sets contains points that are linked by a path.维护一组点,其中每个点都包含由路径链接的点。 For each new edge that you encounter, find which sets each of the points on the edge belong to.对于您遇到的每条新边,找出边上的每个点属于哪个集合。

  1. If they're already both in the same set, there's nothing to do.如果他们已经在同一组中,则无事可做。
  2. If they're in different sets, then replace those two sets with a new set, that's the union of the two.如果它们在不同的集合中,则将这两个集合替换为一个新集合,这就是两者的并集。
  3. If one is in a set, but the other isn't, then add the new point to the set.如果一个在集合中,而另一个不在,则将新点添加到集合中。
  4. If they're both not already in sets, make a new set and add both points.如果它们都不在集合中,请创建一个新集合并添加两个点。

Once you've iterated through all the edges in this fashion, see how many sets you've got.以这种方式遍历所有边缘后,看看您有多少组。 If there's more than one, then your graph is not connected.如果不止一个,则您的图表未连接。

To see this in action, consider your first example.要查看实际效果,请考虑您的第一个示例。

  • Initially, our set of sets is empty.最初,我们的集合集是空的。 {}
  • Edge 1 4 is case 4, since neither point is in a set yet.边 1 4 是情况 4,因为这两个点都不在集合中。 So make a new set with both points in. {{1,4}}因此,制作一个包含两个点的新集合。 {{1,4}}
  • Edge 4 5 is case 3, since 4 is already in a set.边 4 5 是情况 3,因为 4 已经在一个集合中。 So add 5 to the set.因此,将 5 添加到集合中。 {{1,4,5}}
  • Edge 2 6 is case 4, since neither point is in a set yet.边 2 6 是情况 4,因为这两个点都不在集合中。 Make a new set {{1,4,5},{2,6}}制作一个新集合{{1,4,5},{2,6}}
  • Edge 2 4 is case 2, since 2 and 4 are in different sets.边 2 4 是情况 2,因为 2 和 4 在不同的集合中。 Delete both those sets and replace them with their union.删除这两个集合并用它们的并集替换它们。 {{1,4,5,2,6}} . {{1,4,5,2,6}}
  • Edge 5 2 is case 1, since 2 and 5 are already in the same set.边 5 2 是情况 1,因为 2 和 5 已经在同一个集合中。

At the end of the process, there's just one set, so the graph is connected.在这个过程的最后,只有一组,所以图是连通的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM