程式碼隨想錄演算法訓練營第五十六天 | 98.所有可達路徑

深蓝von發表於2024-07-06

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 ;
}

相關文章