- 第 161 篇 -
Date: 2026 - 02- 07
Author: 郑龙浩(仟墨)
2026-02-06 周四
文章目录
-
- [2026-02-06 周四](#2026-02-06 周四)
-
- [1_卡码网98 可达路径](#1_卡码网98 可达路径)
- 2_力扣797_所有可能的路径
1_卡码网98 可达路径
算法DFS
题目描述
给定一个有 n 个节点的有向无环图,节点编号从 1 到 n。请编写一个函数,找出并返回所有从节点 1 到节点 n 的路径。每条路径应以节点编号的列表形式表示。
输入描述
第一行包含两个整数 N,M,表示图中拥有 N 个节点,M 条边
后续 M 行,每行包含两个整数 s 和 t,表示图中的 s 节点与 t 节点中有一条路径
输出描述
输出所有的可达路径,路径中所有节点之间空格隔开,每条路径独占一行,存在多条路径,路径输出的顺序可任意。如果不存在任何一条路径,则输出 -1。
注意输出的序列中,最后一个节点后面没有空格! 例如正确的答案是 1 3 5,而不是 1 3 5 , 5后面没有空格!
cpp
// Date: 2026-02-06 Author:郑龙浩
// 1_卡码网98 可达路径
// DFS:用邻接矩阵
// 用时: 1h27min
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
vector <vector<ll>> result; // 存放多个path
vector <ll> path; // 存放一条路径
// dfs: graph[]是邻接阵,x是当前遍历的节点,n是最后一个节点
void dfs(vector<vector<ll>>& graph, ll x, ll n) {
// 1 确定终止条件
if (x == n) { // 如连接到最后一个节点,就将path加入result 且return下
result.push_back(path);
return;
}
// 2 遍历节点x连接的所有节点
for (ll i = 1; i <= n; i++) {
if (graph[x][i] == 1) { // 如x指向i,就继续以i为节点,寻找i连接的下一个节点
path.push_back(i); // 插入下一个节点
dfs(graph, i, n); // 查找i连接的点
path.pop_back(); // 回溯,执行完dfs(graph, i, n)后,i节点的所有的连接节点都找完了,需要退回到前一个指向i的节点去
}
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
ll N, M, s, t;
cin >> N >> M;
vector <vector<ll>> graph(N + 1, vector<ll>(N + 1, 0)); // 邻接矩阵(相连为1,不相连为0)
while (M--) { // 所有的边
cin >> s >> t;
graph[s][t] = 1;
}
// DFS 深搜
// 注意:在执行dfs之前,要先在path中存储第一个节点
path.push_back(1);
dfs(graph, 1, N);
// 排序结果,按字典序输出(可以不写)
sort(result.begin(), result.end());
// 打印result
// 特容易忘:如果没有任何的路径,就输出-1(注意)
if (result.size() == 0) {
cout << -1;
return 0;
}
for (auto path : result) {
ll len = path.size();
for (ll i = 0; i < len - 1; i++) {
cout << path[i] << ' ';
}
cout << path[len - 1] << '\n'; // 最后一个节点后,没有空格
}
return 0;
}
2_力扣797_所有可能的路径
给你一个有 n 个节点的 有向无环图(DAG) ,请你找出从节点 0 到节点 n-1 的所有路径并输出(不要求按特定顺序)
graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j]存在一条有向边)。
算法
cpp
// Date: 2026-02-06 Author:郑龙浩
// 1_卡码忘98 可达路径
// DFS:用邻接矩阵
// 用时: 1h27min
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
vector <vector<ll>> result; // 存放多个path
vector <ll> path; // 存放一条路径
// dfs: graph[]是邻接阵,x是当前遍历的节点,n是最后一个节点
void dfs(vector<vector<ll>>& graph, ll x, ll n) {
// 1 确定终止条件
if (x == n) { // 如连接到最后一个节点,就将path加入result 且return下
result.push_back(path);
return;
}
// 2 遍历节点x连接的所有节点
for (ll i = 1; i <= n; i++) {
if (graph[x][i] == 1) { // 如x指向i,就继续以i为节点,寻找i连接的下一个节点
path.push_back(i); // 插入下一个节点
dfs(graph, i, n); // 查找i连接的点
path.pop_back(); // 回溯,执行完dfs(graph, i, n)后,i节点的所有的连接节点都找完了,需要退回到前一个指向i的节点去
}
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
ll N, M, s, t;
cin >> N >> M;
vector <vector<ll>> graph(N + 1, vector<ll>(N + 1, 0)); // 邻接矩阵(相连为1,不相连为0)
while (M--) { // 所有的边
cin >> s >> t;
graph[s][t] = 1;
}
// DFS 深搜
// 注意:在执行dfs之前,要先在path中存储第一个节点
path.push_back(1);
dfs(graph, 1, N);
// 排序结果,按字典序输出(可以不写)
sort(result.begin(), result.end());
// 打印result
// 特容易忘:如果没有任何的路径,就输出-1(注意)
if (result.size() == 0) {
cout << -1;
return 0;
}
for (auto path : result) {
ll len = path.size();
for (ll i = 0; i < len - 1; i++) {
cout << path[i] << ' ';
}
cout << path[len - 1] << '\n'; // 最后一个节点后,没有空格
}
return 0;
}