问题简介:
输入样例:
5 7
2 1
3 1
4 1
4 2
5 2
5 3
5 4
1
输出样例:
Path 1: 1 2 4 5 3 1
Path 2: 1 3 5 2 4 1
Path 3: 1 3 5 4 2 1
Path 4: 1 4 2 5 3 1
算法简介:深度优先遍历(Depth First Search,DFS)算法是指在图或树中,朝着一个节点的子节点进行遍历,直达满足结束要求再进行回溯。
设计思路:依据算法的基本思想,利用递归来实现DFS算法。DFS的核心思想是一直往下遍历。比如在二叉树中,从根节点往下,遍历更节点左节点i。再遍历i的子节点k,直到遍历到叶子节点,才完成一次遍历的结果。然后回溯到叶子节点的上一个节点x,再继续遍历x的下一个子节点。上述重复的过程可利用递归函数实现。
代码:
/*dfs算法之哈密顿图*/
#include <iostream>
#include <vector>
using namespace std;
const int maxn = 15;
//记录两点之间是否有通路,graph[v1][v2]=true表示v1、v2间存在通路
bool Graph[maxn][maxn] = { false };
bool vis[maxn] = { false }; //记录顶点是否被访问
int n, e; //顶点和边的条数
int s; //给定的路径起点
vector<int>path; //保存路径的数组
int cnt = 0; //记录回路的数量
void dfs(int v, int number)
{
if (v==s&&number==n) //当所有的节点都被访问并回到起点时,哈密顿图形成
{
cnt++;
cout << "path" << cnt << ":";
for (int x : path)
{
cout << " " << x;
}
cout << endl;
return;
}
for (int i = 1; i <= n; i++)
{
if (!vis[i] && Graph[v][i]) //节点i未被访问,并v和i之间存在路径
{
vis[i] = true;
path.push_back(i);
dfs(i, number + 1); //递归节点i的下一个子节点
path.pop_back(); //将当递归完成后,i的所有的子节点都被遍历,将i出栈
vis[i] = false; //回溯,重置节点的状态
}
}
}
int main()
{
cin >> n >> e;
while (e--)
{
int v1, v2;
cin >> v1 >> v2;
Graph[v1][v2] = Graph[v2][v1] = true;
}
cin >> s;
path.push_back(s);
dfs(s, 0);
return 0;
}
运行结果:
总结:dfs算法的理解是从一个节点开始,一直往下遍历其子节点,直到满足结束条件。其核心是递归和回溯。需要对递归过程有一定的了解,递归往下的过程即是遍历子节点的过程,递归往上的过程即是回溯的过程。将哈密顿图中的每个与节点i相连的节点当作其子节点,利用dfs可以完成哈密顿图的遍历过程。