华为OD机试真题 新系统【图的遍历】

图的遍历(Java/Py/C/C++/Js/Go)题解

华为OD机试真题 新系统 华为OD上机考试真题新系统 9月9号 100分题型

华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解

题目内容

给定一个无向图,顶点编号从 1 1 1 到 n n n;从顶点 1 1 1 出发,进行深度优先搜索(DFS),当某个顶点有多个邻接点时,按照编号从小到大的顺序依次访问,输出遍历过程中访问顶点的顺序。

1 ≤ n ≤ 100 1 \le n \le 100 1≤n≤100, 0 ≤ m ≤ 100 0 \le m \le 100 0≤m≤100。若不连通,DFS 从顶点 1 1 1 出发无法遍历所有顶点,输出只包含可达顶点。输入保证没有自环如 ( i , i ) (i,i) (i,i),即顶点到自身的边;同时输入保证不会有多条相同的边,如 ( 1 , 2 ) (1,2) (1,2) 出现两次。

输入描述

  • 整数 n n n, m m m:表示顶点数和边数;
  • 二维数组 graph:每个元素有两个整数 u u u, v v v,表示 u u u 和 v v v 之间有一条无向边;

输出描述

  • 数组:数组元素表示深度优先搜索访问顶点的顺序(从 1 1 1 开始);

样例1

输入

复制代码
6 5
1 2
1 3
2 4
3 5
3 6

输出

复制代码
1,2,4,3,5,6

说明

  • 从 1 1 1 出发,邻接点有 { 2 , 3 } \{2,3\} {2,3},选小的 2 2 2
  • 从 2 2 2 出发,邻接点有 { 1 , 4 } \{1,4\} {1,4}, 1 1 1 已访问,选 4 4 4
  • 4 4 4 没有未访问邻接点,回溯到 2 2 2,回溯到 1 1 1,下一个未访问的是 3 3 3
  • 从 3 3 3 出发,邻接点有 { 1 , 5 , 6 } \{1,5,6\} {1,5,6}, 1 1 1 已访问,选小的 5 5 5
  • 5 5 5 没有未访问邻接点,回溯到 3 3 3,下一个未访问的是 6 6 6; 6 6 6 结束,遍历完成。最终访问顺序为 1 , 2 , 4 , 3 , 5 , 6 1,2,4,3,5,6 1,2,4,3,5,6

样例2

输入

复制代码
5 2
1 2
3 4

输出

复制代码
1,2

说明

  • 从 1 1 1 出发,邻接点有 { 2 } \{2\} {2},选 2 2 2
  • 从 2 2 2 出发,邻接点有 { 1 } \{1\} {1}, 1 1 1 已访问,没有未访问邻接点,回溯到 1 1 1
  • 1 1 1 没有其他未访问邻接点,遍历结束。顶点 3 3 3、 4 4 4、 5 5 5 与 1 1 1 不连通,无法到达,因此不输出。最终访问顺序为 1 , 2 1,2 1,2

题解

思路:DFS

  1. 先利用给出的边,构造出联接矩阵
  2. 利用递归回溯从获取从1开始顶点访问顺序,主要注意下面几点:
    • 防止重复访问,可以使用vis布尔数组去重。
    • 按照编号从小到大的顺序依次访问。可以按顺序选择与当前相邻顶点访问。

C++

cpp 复制代码
#include <bits/stdc++.h>
#include <vector>
using namespace std;

// 递归访问
void dfs(int index, vector<bool>& vis, vector<int>& path, vector<vector<bool>>& edges) {
    vis[index] = true;
    path.push_back(index);
    for (int i = 1; i < edges[index].size(); i++) {
        if (!edges[index][i]) {
            continue;
        }
        if (vis[i]) {
            continue;
        }
        dfs(i, vis, path, edges);
    }
}

vector<int> solve(int n, int m, vector<vector<int>>& graph) {
    vector<int> ans;
    // 联接矩阵
    vector<vector<bool>> edges(n + 1, vector<bool>(n + 1, false));
    for (int i = 0; i < m; i++) {
        int u = graph[i][0];
        int v = graph[i][1];
        edges[u][v] = true;
        edges[v][u] = true;
    }
    // 去重
    vector<bool> vis(n + 1, false);
    // 递归获取访问顺序
    dfs(1, vis, ans, edges);
    return ans;
}


int main() {
    int n,m;
    cin >> n >> m;
    vector<vector<int>> graph(m);
    for (int i = 0; i < m; i++) {
        int u,v;
        cin >> u >> v;
        graph[i] = {u,v};
    }
    vector<int> ans = solve(n, m, graph);
    for (int i = 0; i < ans.size(); i++) {
        if (i > 0) {
            cout << ",";
        }
        cout << ans[i];
    }
    return 0;
}

Java

java 复制代码
import java.util.*;

public class Main {

    // 递归访问
    static void dfs(int index, boolean[] vis, ArrayList<Integer> path, boolean[][] edges) {
        vis[index] = true;
        path.add(index);

        for (int i = 1; i < edges[index].length; i++) {
            if (!edges[index][i]) {
                continue;
            }
            if (vis[i]) {
                continue;
            }
            dfs(i, vis, path, edges);
        }
    }

    static ArrayList<Integer> solve(int n, int m, int[][] graph) {
        ArrayList<Integer> ans = new ArrayList<>();

        // 联接矩阵
        boolean[][] edges = new boolean[n + 1][n + 1];

        for (int i = 0; i < m; i++) {
            int u = graph[i][0];
            int v = graph[i][1];
            edges[u][v] = true;
            edges[v][u] = true;
        }

        // 去重
        boolean[] vis = new boolean[n + 1];

        // 递归获取访问顺序
        dfs(1, vis, ans, edges);

        return ans;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        int m = sc.nextInt();

        int[][] graph = new int[m][2];

        for (int i = 0; i < m; i++) {
            int u = sc.nextInt();
            int v = sc.nextInt();
            graph[i][0] = u;
            graph[i][1] = v;
        }

        ArrayList<Integer> ans = solve(n, m, graph);

        for (int i = 0; i < ans.size(); i++) {
            if (i > 0) {
                System.out.print(",");
            }
            System.out.print(ans.get(i));
        }
    }
}

Python

python 复制代码
# 递归访问
def dfs(index, vis, path, edges):
    vis[index] = True
    path.append(index)

    for i in range(1, len(edges[index])):
        if not edges[index][i]:
            continue
        if vis[i]:
            continue
        dfs(i, vis, path, edges)


def solve(n, m, graph):
    ans = []

    # 联接矩阵
    edges = [[False] * (n + 1) for _ in range(n + 1)]

    for i in range(m):
        u = graph[i][0]
        v = graph[i][1]
        edges[u][v] = True
        edges[v][u] = True

    # 去重
    vis = [False] * (n + 1)

    # 递归获取访问顺序
    dfs(1, vis, ans, edges)

    return ans


n, m = map(int, input().split())

graph = []
for _ in range(m):
    u, v = map(int, input().split())
    graph.append([u, v])

ans = solve(n, m, graph)

print(",".join(map(str, ans)))

JavaScript

js 复制代码
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const lines = [];

rl.on('line', (line) => {
    lines.push(line);
});

rl.on('close', () => {
    let index = 0;

    const [n, m] = lines[index++].trim().split(/\s+/).map(Number);

    const graph = new Array(m);

    for (let i = 0; i < m; i++) {
        const [u, v] = lines[index++].trim().split(/\s+/).map(Number);
        graph[i] = [u, v];
    }

    // 递归访问
    function dfs(index, vis, path, edges) {
        vis[index] = true;
        path.push(index);

        for (let i = 1; i < edges[index].length; i++) {
            if (!edges[index][i]) {
                continue;
            }
            if (vis[i]) {
                continue;
            }
            dfs(i, vis, path, edges);
        }
    }

    function solve(n, m, graph) {
        const ans = [];

        // 联接矩阵
        const edges = Array.from(
            { length: n + 1 },
            () => new Array(n + 1).fill(false)
        );

        for (let i = 0; i < m; i++) {
            const u = graph[i][0];
            const v = graph[i][1];
            edges[u][v] = true;
            edges[v][u] = true;
        }

        // 去重
        const vis = new Array(n + 1).fill(false);

        // 递归获取访问顺序
        dfs(1, vis, ans, edges);

        return ans;
    }

    const ans = solve(n, m, graph);

    console.log(ans.join(','));
});

Go

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
)

// 递归访问
func dfs(index int, vis []bool, path *[]int, edges [][]bool) {
	vis[index] = true
	*path = append(*path, index)

	for i := 1; i < len(edges[index]); i++ {
		if !edges[index][i] {
			continue
		}
		if vis[i] {
			continue
		}
		dfs(i, vis, path, edges)
	}
}

func solve(n int, m int, graph [][]int) []int {
	ans := []int{}

	// 联接矩阵
	edges := make([][]bool, n+1)
	for i := 0; i <= n; i++ {
		edges[i] = make([]bool, n+1)
	}

	for i := 0; i < m; i++ {
		u := graph[i][0]
		v := graph[i][1]
		edges[u][v] = true
		edges[v][u] = true
	}

	// 去重
	vis := make([]bool, n+1)

	// 递归获取访问顺序
	dfs(1, vis, &ans, edges)

	return ans
}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, m int
	fmt.Fscan(in, &n, &m)

	graph := make([][]int, m)

	for i := 0; i < m; i++ {
		var u, v int
		fmt.Fscan(in, &u, &v)
		graph[i] = []int{u, v}
	}

	ans := solve(n, m, graph)

	for i := 0; i < len(ans); i++ {
		if i > 0 {
			fmt.Fprint(out, ",")
		}
		fmt.Fprint(out, ans[i])
	}
}

C语言

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

// 递归访问
void dfs(int index, int *vis, int *path, int *pathSize, int **edges, int n) {
    vis[index] = 1;
    path[(*pathSize)++] = index;

    for (int i = 1; i <= n; i++) {
        if (!edges[index][i]) {
            continue;
        }
        if (vis[i]) {
            continue;
        }
        dfs(i, vis, path, pathSize, edges, n);
    }
}

int *solve(int n, int m, int **graph, int *ansSize) {
    // 联接矩阵
    int **edges = (int **)malloc((n + 1) * sizeof(int *));

    for (int i = 0; i <= n; i++) {
        edges[i] = (int *)calloc(n + 1, sizeof(int));
    }

    for (int i = 0; i < m; i++) {
        int u = graph[i][0];
        int v = graph[i][1];
        edges[u][v] = 1;
        edges[v][u] = 1;
    }

    // 去重
    int *vis = (int *)calloc(n + 1, sizeof(int));

    int *ans = (int *)malloc((n + 1) * sizeof(int));
    *ansSize = 0;

    // 递归获取访问顺序
    dfs(1, vis, ans, ansSize, edges, n);

    free(vis);

    for (int i = 0; i <= n; i++) {
        free(edges[i]);
    }
    free(edges);

    return ans;
}

int main() {
    int n, m;
    scanf("%d %d", &n, &m);

    int **graph = (int **)malloc(m * sizeof(int *));

    for (int i = 0; i < m; i++) {
        int u, v;
        scanf("%d %d", &u, &v);

        graph[i] = (int *)malloc(2 * sizeof(int));
        graph[i][0] = u;
        graph[i][1] = v;
    }

    int ansSize = 0;
    int *ans = solve(n, m, graph, &ansSize);

    for (int i = 0; i < ansSize; i++) {
        if (i > 0) {
            printf(",");
        }
        printf("%d", ans[i]);
    }

    free(ans);

    for (int i = 0; i < m; i++) {
        free(graph[i]);
    }
    free(graph);

    return 0;
}
相关推荐
哪 吒3 天前
华为OD机试 - 云服务安全策略最优选择 - 深度优先搜索DFS(Java 新系统 200分)
java·华为od·深度优先
无限码力14 天前
8.26华为OD机试真题 新系统【字符串回文判断】
算法·华为od·华为od机考·华为od机试·华为od上机考试真题·华为od最新机试真题题解·华为od机试真题题库
s180579163622 个月前
餐饮小程序GEO优化
华为od
令狐掌门2 个月前
2026华为OD面试题020:日志文件异常检测
算法·leetcode·华为od
令狐掌门2 个月前
2026华为OD面试题018:智能成绩表
华为od
令狐掌门2 个月前
2026华为OD面试题002:路口最短时间问题
华为od·华为od面试题
令狐掌门2 个月前
2026华为OD面试题001:两个字符串间的最短路径问题
华为od·华为od面试题
2601_962072553 个月前
李梦娇常识4600问|题库|打印版
sql·华为od·华为·c#·华为云·.net·harmonyos
HEADKON3 个月前
Larotretinib拉罗替尼治NTRK融合实体瘤,神经系统反应多为一过性
华为od