代码随想录算法训练营第五十六天 | 98.所有可达路径

98.所有可达路径

题目链接 文章讲解


邻接矩阵法

邻接矩阵使用二维数组来表示图结构。邻接矩阵是从节点的角度来表示图,有多少节点就申请多大的二维数组

为了节点标号和下标对其,有n个节点的图申请(n + 1) * (n + 1)的空间

vector<vector<int>> graph(n + 1, vector<int>(n + 1, 0));

输入m条边构造图

while (m--) {
    cin >> s >> t;
    // 使用邻接矩阵,1表示节点s指向节点t有一条边
    graph[s][t] = 1;
}

完整代码:

#include <iostream>
#include <vector>

using namespace std;

void dfs(const vector<vector<int>>& graph, int x, int n);

vector<vector<int>> result; // 结果集
vector<int> path; // 当前路径


int main() {
    
    int N; // 图中有N个节点
    int M; // 图中有M条边
    
    int s, t; // 两个相邻的节点
    
    while(cin >> N >> M) {
        vector<vector<int>> graph(N + 1, vector<int>(N + 1, 0)); // 邻接矩阵存放图
        while(M--) {
            cin >> s >> t;
            graph[s][t] = 1; // 1表示有一条边连接s->t  
        }
        
        // 第一个节点加入路径
        path.push_back(1);
        dfs(graph, 1, N);
    
    
        if(result.size() == 0) cout << -1 << endl;
        
        // 输出结果
        for(auto path : result) {
            for(int i = 0; i < path.size() - 1; ++i) {
                cout << path[i] << " ";
            }
            cout << path[path.size() - 1] << endl;
        }
    }
    
    
    return 0;
}

void dfs(const vector<vector<int>>& graph, int x, int n) {
    // 遍历到目标节点回收结果
    if(x == n) {
        result.push_back(path);
        return ;
    }
    
    // 遍历图中的每一个节点
    for(int i = 1; i <= n; ++i) {
        if(graph[x][i]) {  // 当前节点到i节点由路径,将i加入路径
            path.push_back(i);
            dfs(graph, i, n); // 进入下一层递归
            path.pop_back(); // 回溯
        }
    }
    
    return ;
}

邻接表写法

邻接表使用数组加链表的方式来表示。邻接表是从边的数量来表示图,有多少条边就申请多大的空间

构造邻接表

vector<list<int>> graph(n + 1); // 邻接表,list为链表

输入m条边构造图

while (m--) {
    cin >> s >> t;
    // 使用邻接表 ,表示 s -> t 是相连的
    graph[s].push_back(t);
}

完整代码:

#include <iostream>
#include <vector>
#include <list>

using namespace std;

void dfs(const vector<list<int>>& graph, int x, int n);

vector<vector<int>> result; // 结果集
vector<int> path; // 当前路径


int main() {
    
    int N; // 图中有N个节点
    int M; // 图中有M条边
    
    int s, t; // 两个相邻的节点
    
    while(cin >> N >> M) {
        vector<list<int>> graph(N + 1); // 邻接矩阵存放图
        while(M--) {
            cin >> s >> t;
            graph[s].push_back(t); // 表示s到t有一条边连接s->t  
        }
        
        
        path.push_back(1);
        dfs(graph, 1, N);
    
    
        if(result.size() == 0) cout << -1 << endl;
    
        for(auto path : result) {
            for(int i = 0; i < path.size() - 1; ++i) {
                cout << path[i] << " ";
            }
            cout << path[path.size() - 1] << endl;
        }
    }
    
    
    return 0;
}

void dfs(const vector<list<int>>& graph, int x, int n) {
    if(x == n) {
        result.push_back(path);
        return ;
    }
    
    for(int i : graph[x]) {
        path.push_back(i);
        dfs(graph, i, n);
        path.pop_back();
    }
    
    return ;
}
posted @ 2024-07-06 14:20  深蓝von  阅读(2)  评论(0编辑  收藏  举报