zoukankan      html  css  js  c++  java
  • 图的遍历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
    ", 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;
    
    }
    
  • 相关阅读:
    apue学习笔记(第十二章 线程控制)
    apue学习笔记(第十一章 线程)
    apue学习笔记(第十章 信号)
    apue学习笔记(第九章 进程关系)
    apue学习笔记(第八章 进程控制)
    apue学习笔记(第七章 进程环境)
    apue学习笔记(第六章 系统数据文件和信息)
    apue学习笔记(第五章 标准I/O)
    apue学习笔记(第四章 文件和目录)
    apue学习笔记(第三章 文件I/O)
  • 原文地址:https://www.cnblogs.com/DengSchoo/p/12664827.html
Copyright © 2011-2022 走看看