查找有向图中两个顶点之间是否存在路径
给定一个有向图和其中的两个顶点,检查是否存在从第一个给定顶点到第二个顶点的路径。
Consider the following Graph:
Input : (u, v) = (1, 3)
Output: Yes
Explanation: There is a path from 1 to 3, 1 -> 2 -> 3
Input : (u, v) = (3, 0)
Output: No
Explanation: There is no path from 3 to 6
Approach:
可以使用广度优先搜索BFS或深度优先搜索DFS来查找两个顶点之间的路径。在BFS或DFS中取第一个顶点作为源点,然后开始执行。如果在我们的遍历中找到第二个顶点,则返回 true 否则返回 false。
Alogrithm:
- 下面的实现是使用 BFS
- 创建一个队列和一个最初填充为 0、大小为 V 的visited数组,其中 V 是顶点数
- 在队列中插入起始节点,即把u 推入队列并将u 标记为已访问
- while循环该队列,直到队列不为空
- 使队列的前元素出列,迭代其所有相邻元素。如果有相邻元素是目标顶点,则返回 true。推入队列中所有相邻和未访问的顶点并将它们标记为已访问
- 由于 BFS 中未到达目的地,因此返回 false
Code:
static class Graph {
int V;
List<Integer>[] adj;
public Graph(int V) {
this.V = V;
adj = new List[V];
for (int i = 0; i < V; i++) {
adj[i] = new LinkedList<>();
}
}
void addEdge(int u, int v) {
adj[u].add(v);
}
/**
* @param s 起始顶点 source
* @param d 结束顶点 destination
* @return
*/
boolean isReachable(int s, int d) {
boolean[] visited = new boolean[V];
Queue<Integer> queue = new LinkedList<>();
queue.offer(s);
visited[s] = true;
while (!queue.isEmpty()) {
int u = queue.poll();
for (int v : adj[u]) {
if (v == d) return true;
if (!visited[v]) {
visited[v] = true;
queue.offer(v);
}
}
}
return false;
}
public static void main(String args[]) {
// Create a graph given in the above diagram
Graph g = new Graph(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
int u = 1;
int v = 3;
if (g.isReachable(u, v))
System.out.println("There is a path from " + u + " to " + v);
else
System.out.println("There is no path from " + u + " to " + v);
u = 3;
v = 1;
if (g.isReachable(u, v))
System.out.println("There is a path from " + u + " to " + v);
else
System.out.println("There is no path from " + u + " to " + v);
}
/**
* There is a path from 1 to 3
* There is no path from 3 to 1
*/
}