4.2 Given a directed graph, design an algorithm to find out whether thereis a route between two nodes.
译文:给定一个有向图,设计一个算法判断两节点之间是否存在路径。
这个题目实际上就是考察图的遍历,前面已经介绍了图的两种遍历方式:BFS和DFS 。这里判断两个节点之间是否存在路径,实质就是给定一个开始顶点,然后判断能否遍历到另一个指定顶点。这种情况下,我们采用BFS遍历判断。
先构建一个有向图(前面我们构建的都是无向图)
#include <iostream> #include <list> using namespace std; class graph { public: graph(int v) :vertex(v){ adj = new list<int>[v]; } void addEdge(int v, int w); bool BFS(int vStart, int vEnd); private: int vertex; list<int> *adj; }; //v:边的首顶点;w:边的尾顶点 void graph::addEdge(int v, int w) { adj[v].push_back(w); }
构建有向图:
int main() { graph g(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); if (g.BFS(2, 1)) cout << "yes" << endl; else cout << "no" << endl; return 0; }BFS
bool graph::BFS(int vStart, int vEnd) { bool *visited = new bool[vertex]; memset(visited, false, vertex); list<int> queue;//利用链表构建一个队列 visited[vStart] = true;//表示开始访问 queue.push_back(vStart);//开始顶点入队 list<int>::iterator iter; //队列中的顶点就是访问的顶点 while (!queue.empty()) { vStart = queue.front();//这里有个优先级,邻接表中链表的头节点优先级最高,依次降低 queue.pop_front();//已访问顶点出队 if (vStart == vEnd)//如果已访问的顶点恰好是指定目的顶点则表明有路径 return true; //将与开始顶点最近的顶点,也就是链表中的顶点依次入队 for (iter = adj[vStart].begin(); iter != adj[vStart].end(); ++iter) { if (!visited[*iter]) { visited[*iter] = true;//标记即将访问,事实上,进入队列了就是要访问的 queue.push_back(*iter);//从链表头节点到尾节点依次入队 } } } return false; }