constint N = 510, M = 3000; // N 最大点数 M 最大边数 structedge// 边 { int v, w, ne; // v 终点 w 权值 ne 下一条 }; edge e[M]; // 边集 int idx, h[N]; // h[N] 点的第一条出边 idx边数
voidadd(int a, int b, int c)// 加边 { // 头插法 e[idx] = {b, c, h[a]}; h[a] = idx++; } voiddfs(int u, int fa) { // 从第一个条出边开始,到达-1找完,下一次找的是下一条e[i].ne for (int i = h[u]; ~i; i = e[i].ne) { int v = e[i].v, w = e[i].w; if (v == fa) // 不能往回找 continue; cout << u << " " << v << " " << w << endl; // 访问操作 dfs(v, u); // 递归 } } voidfigure() { int n, m, a, b, c; // n 点数 m 边数 cin >> n >> m; memset(h, -1, sizeof h); // 初始化为-1 for (int i = 1; i <= m; i++) // 输入边 { cin >> a >> b >> c; // a、b两顶点,c表示权值 add(a, b, c); add(b, a, c); } dfs(1, 0); // 根节点开始dfs return; }
搜索
深度优先搜索(DFS)
广度优先搜索(BFS)
实现
系统栈
队列
搜索顺序
一搜到底
逐层扩展
触碰点的时机
多次:入、下、回、离
两次:入队、出队
时间复杂度
不回溯 $O(n+m)$ ,回溯 $O(指数级)$
$O(n+m)$
连通性问题
适合
适合
方案数问题
适合
不适合
最少步数问题
不适合
适合
深度优先搜索(DFS)
语句时机
一般情况:进入时机、下走时机、上回时机、离开时机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
constint N = 510, M = 3000; // N 最大点数 M 最大边数 // 链式邻接表 vector<int> h[N]; // 点的所有出边 voiddfs(int u, int fa) { // 进入时机 for (auto v : h[u]) { if (v == fa) continue; // 下走时机 dfs(v, u); // 上回时机 } // 离开时机 }