图的遍历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;
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号