建圖

n1ce2cv發表於2024-09-12

建圖

鄰接矩陣

#include <iostream>
#include <vector>

using namespace std;

// 點的最大數量
int MAX_N = 11;

// 鄰接矩陣方式建圖
vector<vector<int>> graph(MAX_N, vector<int>(MAX_N));

// 初始化,下標從 1 開始
void build(int n) {
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            graph[i][j] = 0;
}

// 有向圖建圖
void directedGraph(vector<vector<int>> &edges) {
    for (const auto &edge: edges)
        graph[edge[0]][edge[1]] = edge[2];
}

// 無向圖建圖
void undirectedGraph(vector<vector<int>> &edges) {
    for (const auto &edge: edges) {
        graph[edge[0]][edge[1]] = edge[2];
        graph[edge[1]][edge[0]] = edge[2];
    }
}

void traversal(int n) {
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j)
            cout << graph[i][j] << " ";
        cout << endl;
    }
}

int main() {
    int n1 = 4;
    vector<vector<int>> edges1 = {{1, 3, 6},
                                  {4, 3, 4},
                                  {2, 4, 2},
                                  {1, 2, 7},
                                  {2, 3, 5},
                                  {3, 1, 1}};
    build(n1);
    directedGraph(edges1);
    traversal(n1);
    cout << endl;
    int n2 = 5;
    vector<vector<int>> edges2 = {{3, 5, 4},
                                  {4, 1, 1},
                                  {3, 4, 2},
                                  {5, 2, 4},
                                  {2, 3, 7},
                                  {1, 5, 5},
                                  {4, 2, 6}};
    build(n2);
    undirectedGraph(edges2);
    traversal(n2);
}

鄰接表

#include <iostream>
#include <vector>
#include <forward_list>

using namespace std;

// 點的最大數量
int MAX_N = 11;

// 鄰接表方式建圖
// 無權
// vector<forward_list<int>> graph(MAX_N);
// 帶權
vector<forward_list<pair<int, int>>> graph(MAX_N);

// 初始化,下標從 1 開始
void build(int n) {
    for (int i = 0; i <= n; ++i)
        graph[i].clear();
}

// 有向圖建圖
void directedGraph(vector<vector<int>> &edges) {
    for (const auto &edge: edges) {
        // edge[0]: u edge[1]: v, u->v
        // edge[2] 為權重
        // forward_list 只能頭插,使用 list 可以尾插
        graph[edge[0]].emplace_front(make_pair(edge[1], edge[2]));
    }
}

// 無向圖建圖
void undirectedGraph(vector<vector<int>> &edges) {
    for (const auto &edge: edges) {
        graph[edge[0]].emplace_front(make_pair(edge[1], edge[2]));
        graph[edge[1]].emplace_front(make_pair(edge[0], edge[2]));
    }
}

void traversal(int n) {
    for (int i = 1; i <= n; ++i) {
        cout << i << "(鄰居、邊權): ";
        auto it = begin(graph[i]);
        while (it != end(graph[i])) {
            cout << "(" << (*it).first << ", " << (*it).second << ")";
            it++;
        }
        cout << endl;
    }
}

int main() {
    int n1 = 4;
    vector<vector<int>> edges1 = {{1, 3, 6},
                                  {4, 3, 4},
                                  {2, 4, 2},
                                  {1, 2, 7},
                                  {2, 3, 5},
                                  {3, 1, 1}};
    build(n1);
    directedGraph(edges1);
    traversal(n1);
    cout << endl;
    int n2 = 5;
    vector<vector<int>> edges2 = {{3, 5, 4},
                                  {4, 1, 1},
                                  {3, 4, 2},
                                  {5, 2, 4},
                                  {2, 3, 7},
                                  {1, 5, 5},
                                  {4, 2, 6}};
    build(n2);
    undirectedGraph(edges2);
    traversal(n2);
}

鏈式前向星

#include <iostream>
#include <vector>

using namespace std;

// 點的最大數量
int MAX_N = 11;

// 邊的最大數量
// 只有鏈式前向星方式建圖需要這個數量
// 注意如果無向圖的最大數量是 m 條邊,數量要準備 m*2
// 因為一條無向邊要加兩條有向邊
int MAX_M = 11;

// 鏈式前向星方式建圖
// 下標:頂點編號,值:該頂點第一條邊的邊號
vector<int> head(MAX_N);
// 下標:邊號,值:下一條邊的邊號
vector<int> nxt(MAX_M);
// 下標:邊號,值:去往的頂點編號
vector<int> to(MAX_M);
// 如果邊有權重,那麼需要這個陣列
vector<int> weight(MAX_M);
// 邊號計數,從 1 開始,0 表示沒有邊
int cnt;

// 初始化,下標從 1 開始
void build(int n) {
    // 鏈式前向星清空
    cnt = 1;
    fill(head.begin(), head.end(), 0);
}

// 鏈式前向星加邊,u->v,w 為權重
void addEdge(int u, int v, int w) {
    // 記錄權重
    weight[cnt] = w;
    // 邊號為 cnt 的邊作為新的頭邊,插入到舊的頭邊之前
    nxt[cnt] = head[u];
    to[cnt] = v;
    head[u] = cnt;
    cnt++;
}

// 有向圖建圖
void directedGraph(vector<vector<int>> &edges) {
    for (const auto &edge: edges)
        addEdge(edge[0], edge[1], edge[2]);
}

// 無向圖建圖
void undirectedGraph(vector<vector<int>> &edges) {
    for (const auto &edge: edges) {
        addEdge(edge[0], edge[1], edge[2]);
        addEdge(edge[1], edge[0], edge[2]);
    }
}

void traversal(int n) {
    for (int i = 1; i <= n; ++i) {
        cout << i << "(鄰居、邊權): ";
        for (int ei = head[i]; ei > 0; ei = nxt[ei])
            cout << "(" << to[ei] << "," << weight[ei] << ")";
        cout << endl;
    }
}

int main() {
    int n1 = 4;
    vector<vector<int>> edges1 = {{1, 3, 6},
                                  {4, 3, 4},
                                  {2, 4, 2},
                                  {1, 2, 7},
                                  {2, 3, 5},
                                  {3, 1, 1}};
    build(n1);
    directedGraph(edges1);
    traversal(n1);
    cout << endl;
    int n2 = 5;
    vector<vector<int>> edges2 = {{3, 5, 4},
                                  {4, 1, 1},
                                  {3, 4, 2},
                                  {5, 2, 4},
                                  {2, 3, 7},
                                  {1, 5, 5},
                                  {4, 2, 6}};
    build(n2);
    undirectedGraph(edges2);
    traversal(n2);
}

相關文章