图的遍历dfs和bfs
图的遍历dfs和bfs
深度优先遍历图的主要思想就是:
首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点:当没有未访问过的顶点时,则回到上一个顶点,继续试探访问别的顶点,知道所以的顶点都被访问过。
对于深度优先遍历图来说:
就是沿着一个分支走到底,发现无顶点可访问,则回溯一个,然后继续访问其它未访问过的顶点,直到所有的顶点都被访问过为止。
采用的数据结构:
二维邻接矩阵来表示图(无向图)的关系
edges[i][j] = 1 ;表示顶点i 到 j有边
edges[i][j] = INF;表示顶点i到j无边
代码实现:
#include <stdio.h>
int v[101], sum , n, e[101][101];
void dfs(int cur) {
printf("%d ", cur);
sum++; // 每访问一个顶点sum++
if (sum == n) return; // 所有顶点已经访问过
for (int i = 1; i <= n;i++) {
if (edges[cur][i] == 1 && v[i] == 0) { //可以访问并且 没有被访问过
v[i] = 1; // 标记顶点i已经访问过
dfs(i); //从顶点i再出发继续遍历
}
}
return;
}
int main() {
int i, j, m, a, b;
scanf("%d%d", &n, &m);
for (int i = 1;i <= n ; i++) {
for(int j = 1; j <= n; j++) {
if (i == j) e[i][j] = 0;
else e[i][j] = 9999999;//假设这里为正无穷
}
}
for (int i = 1; i < m; i++) {
scanf("%d%d", &a, &b);
edges[a][b] = 1;
edges[b][a] = 1;
}
v[1] = 1;
dfs(1);
return 0;
}
实例演示:
城市旅游的最短路径问题 从1号顶点到n号顶点的最短路径:
/*输入:
5 8
1 2 2
1 5 10
2 3 3
2 5 7
3 1 4
3 4 4
4 5 5
5 3 3
*/
/*输出:
9
*/
#include <stdio.h>
#define MAX 99999999
int sum, e[101][101], n, v[101], min = MAX;
void dfs(int cur, int dis) { // cur表示当前城市, dis表示当前路径
if (dis > min) return; //剪枝策略
if (cur == n) { // 发现已经遍历了全部
if (dis < min) {
min = dis;
}
return;
}
for (int i = 1; i <= n; i++) {
if (e[cur][i] != MAX && v[i] == 0) {
v[i] = 1;
dfs(i, dis + e[cur][i]);
v[i] = 0; //因为要求取最小值 所有要遍历所有情况
}
}
return;
}
int main() {
int i, j, m, a, b, c;
scanf("%d%d", &n, &m); //n个顶点 m条边
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j) e[i][j] = 0;
else e[i][j] = MAX;
}
}
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &a, &b, &c);
e[a][b] = c;//有向图
}
v[1] = 1;
dfs(1,0);
printf("%d\n", min);
}
图的广度优先遍历-最少转机问题
从1号城市到n号城市的最小转机问题,即经历过的边的数量最少
C++实现代码
#include <iostream>
#include <stdio.h>
#include <queue>
using namespace std;
#define MAX 9999999
struct note {
int x;
int s;
note(int xx, int ss) {
x = xx;
s = ss;
}
};
int main() {
int e[51][51] = { 0 }, v[51] = { 0 };
int n, m, a, b, c, start, end, flag = 0;
int cur;
queue<note> q;
scanf("%d %d %d %d", &n, &m, &start, &end);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j) e[i][j] = 0;
else e[i][j] = MAX;
}
}
for (int i = 1; i <= m; i++) {
scanf("%d %d", &a, &b);
e[a][b] = 1;
e[b][a] = 1;
}
q.push(note(start, 0));
v[start] = 1;
while (!q.empty()) {
note cur = q.front();
q.pop();
for (int i = 1; i <= n; i++) {
if (e[cur.x][i] != MAX && v[i] == 0) {
v[i] = 1;
q.push(note(i, cur.s + 1));
if (i == end) {
flag = 1;
break;
}
}
}
if (flag == 1) {
break;
}
}
cout << q.back().s <<endl;
}