Nền tảng Kiến thức - Hành trang tới Tương lai
Card image

Chương trình học


  1. Lý thuyết đồ thị 31
    1. Các khái niệm cơ bản về Lý thuyết Đồ thị
    2. Biểu diễn đồ thị trên máy tính bằng Ma trận kề
    3. Biểu diễn đồ thị trên máy tính bằng Danh sách cạnh
    4. Biểu diễn đồ thị trên máy tính bằng Danh sách kề
    5. Lab 1 - Chuyển Danh sách cạnh sang Ma trận kề
    6. Lab 1.2 - Chuyển Danh sách cạnh sang Danh sách kề
    7. Lab 1.3 - Chuyển Ma trận kề sang Danh sách cạnh
    8. Lab 1.4 - Chuyển Ma trận kề sang Danh sách kề
    9. Lab 1.5 - Chuyển Danh sách kề sang Ma trận kề
    10. Lab 1.6 - Chuyển Danh sách kề sang Danh sách cạnh
    11. Duyệt cây theo chiều sâu DFS (Depth First Search)
    12. Duyệt cây theo chiều rộng BFS (Breadth First Search)
    13. Thuật toán Tìm đường đi giữa 2 đỉnh của Đồ thị bằng C/C++
    14. Lab 2 - Duyệt cây theo chiều sâu DFS (Depth First Search)
    15. Lab 2.2 - Tìm đường đi bằng cách duyệt cây theo chiều sâu DFS (Depth First Search)
    16. Lab 3 - Duyệt cây theo chiều rộng BFS (Breadth First Search)
    17. Lab 3.2 - Tìm đường đi bằng cách duyệt cây theo chiều rộng BFS (Breadth First Search)
    18. Lab 4 - Tìm các thành phần liên thông trên đồ thị vô hướng
    19. Tìm đường đi ngắn nhất bằng Thuật toán Dijkstra
    20. Lab 5 - Tìm đường đi ngắn nhất từ đỉnh S đến tất cả các đỉnh còn lại trên đồ thị (sử dụng thuật toán Dijkstra)
    21. Lab 5.1 - Tìm đường đi ngắn nhất từ đỉnh S đến đỉnh T trên đồ thị (sử dụng thuật toán Dijkstra)
    22. Thuật toán Kruskal – Tìm cây khung (bao trùm) nhỏ nhất
    23. Lab 6 - Tìm cây khung (bao trùm) cực tiểu nhỏ nhất (sử dụng thuật toán Kruskal)
    24. Thuật toán Prim - Tìm cây khung (bao trùm) nhỏ nhất
    25. Lab 6.1 - Tìm cây khung (bao trùm) cực tiểu nhỏ nhất (sử dụng thuật toán PRIM)
    26. Chu trình và đường đi Euler
    27. Lab 7 - Tìm chu trình Euler
    28. Lab 7.1 - Tìm đường đi Euler
    29. Bài toán Luồng cực đại
    30. Lab 8 - Tìm luồng cực đại - sử dụng thuật toán Ford - Fulkerson
    31. Lab 8.1 - Tìm luồng cực đại - sử dụng thuật toán Edmonds - Karp (Shortest path)
  2. Tài liệu tham khảo 2
    1. Kho sách, nguồn tài liệu tham khảo Lập trình C++ - Cấu trúc dữ liệu và Giải thuật
    2. Bài tập Lý thuyết Đồ thị có lời giải
  3. Quy hoạch động 1
    1. Lý thuyết các bài toán sử dụng Quy hoạch động

Chương 1-Bài 18. Lab 4 - Tìm các thành phần liên thông trên đồ thị vô hướng

Tác giả: Dương Nguyễn Phú Cường
Ngày đăng: Hồi xưa đó

Đề bài

Cho đồ thị có hướng G=<V,E> được biểu diễn dưới dạng danh sách cạnh. Hãy viết chương trình liệt kê các thành phần liên thông của đồ thị.

Input

  • Dòng đầu tiên chứa 2 số n, m là số đỉnh và số cạnh của đồ thị (1 <= n <= 1000, 1 <= m <= n*(n-1)/2).
  • M dòng tiếp theo, mỗi dòng là 2 số u, v biểu diễn cạnh u, v của đồ thị (1 <= u, v <= n). Các cạnh được liệt kê theo thứ tự tăng dần của các đỉnh đầu.

Output

  • Ghi ra file văn bản lab_4_output.OUT gồm nhiều dòng, mỗi dòng liệt kê các đỉnh thuộc một thành phần liên thông.
Input Output
12 10
1 4
2 3
3 6
4 5
6 7
8 9
8 10
9 11
11 8
11 12
1 4 5
2 3 6 7
8 9 10 11 12

Giải

  • Source code:
#include<bits/stdc++.h>
#include<iostream>
using namespace std;

int n, m; // n: so dinh, m: so canh
vector<int> adj[1001];
bool visited[1001];
int parent[1001];

void inp() {
  cin >> n >> m;
  for(int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    adj[x].push_back(y);
    
    // Do thi co huong thi comment dong code sau
    adj[y].push_back(x);
  }
  
  // Sap xep cac gia tri trong vector tang dan A-Z
  for(int i = 1; i <= n; i++) {
    sort(adj[i].begin(), adj[i].end());
  }
  
  memset(visited, false, sizeof(visited));
}

void dfs(int u) {
  cout << u << " ";
  // Danh dau la u da duoc ghe tham
  visited[u] = true;
  for(int v: adj[u]) {
    // Neu dinh v chua duoc tham
    if(!visited[v]) {
      dfs(v);
    }
  }
}

void bfs(int u) {
  // Khoi tao
  queue<int> q;
  q.push(u);
  visited[u] = true;
  
  // Lap
  while(!q.empty()) {
    int v = q.front(); // Lay phan tu o dau hang doi
    q.pop(); // xoa bo phan tu o dau ra khoi hang doi
    cout << v << " ";
    for(int x: adj[v]) {
      if(!visited[x]) {
        q.push(x);
        visited[x] = true;
        parent[x] = v; // Ghi nhan cha cua x la v
      }
    }
  }
}

void connected_component() {
  int cnt = 0; // Khoi tao so thanh phan lien thong ban dau cua do thi = 0
  
  // Duyet qua cac dinh
  for(int i = 1; i <= n; i++) {
    if(!visited[i]) {
      ++cnt; // Tang so thanh phan lien thong
      bfs(i);
      cout << endl;
    }
  }
  
  cout << "Tong so thanh phan lien thong: " << cnt;
}

int main() {
  // Chuyen NHAP, XUAT thanh file
  freopen("lab_4_input.INP", "r", stdin);
  freopen("lab_4_output.OUT", "w", stdout);

  // INPUT
  inp();
  
  // OUTPUT: liet ke cac thanh phan lien thong bang DFS / BFS
  connected_component();
}

Các bài học

Chương trình học

Bao gồm Module, Chương, Bài học, Bài tập, Kiểm tra...

Chương trình học


  1. Lý thuyết đồ thị 31
    1. Các khái niệm cơ bản về Lý thuyết Đồ thị
    2. Biểu diễn đồ thị trên máy tính bằng Ma trận kề
    3. Biểu diễn đồ thị trên máy tính bằng Danh sách cạnh
    4. Biểu diễn đồ thị trên máy tính bằng Danh sách kề
    5. Lab 1 - Chuyển Danh sách cạnh sang Ma trận kề
    6. Lab 1.2 - Chuyển Danh sách cạnh sang Danh sách kề
    7. Lab 1.3 - Chuyển Ma trận kề sang Danh sách cạnh
    8. Lab 1.4 - Chuyển Ma trận kề sang Danh sách kề
    9. Lab 1.5 - Chuyển Danh sách kề sang Ma trận kề
    10. Lab 1.6 - Chuyển Danh sách kề sang Danh sách cạnh
    11. Duyệt cây theo chiều sâu DFS (Depth First Search)
    12. Duyệt cây theo chiều rộng BFS (Breadth First Search)
    13. Thuật toán Tìm đường đi giữa 2 đỉnh của Đồ thị bằng C/C++
    14. Lab 2 - Duyệt cây theo chiều sâu DFS (Depth First Search)
    15. Lab 2.2 - Tìm đường đi bằng cách duyệt cây theo chiều sâu DFS (Depth First Search)
    16. Lab 3 - Duyệt cây theo chiều rộng BFS (Breadth First Search)
    17. Lab 3.2 - Tìm đường đi bằng cách duyệt cây theo chiều rộng BFS (Breadth First Search)
    18. Lab 4 - Tìm các thành phần liên thông trên đồ thị vô hướng
    19. Tìm đường đi ngắn nhất bằng Thuật toán Dijkstra
    20. Lab 5 - Tìm đường đi ngắn nhất từ đỉnh S đến tất cả các đỉnh còn lại trên đồ thị (sử dụng thuật toán Dijkstra)
    21. Lab 5.1 - Tìm đường đi ngắn nhất từ đỉnh S đến đỉnh T trên đồ thị (sử dụng thuật toán Dijkstra)
    22. Thuật toán Kruskal – Tìm cây khung (bao trùm) nhỏ nhất
    23. Lab 6 - Tìm cây khung (bao trùm) cực tiểu nhỏ nhất (sử dụng thuật toán Kruskal)
    24. Thuật toán Prim - Tìm cây khung (bao trùm) nhỏ nhất
    25. Lab 6.1 - Tìm cây khung (bao trùm) cực tiểu nhỏ nhất (sử dụng thuật toán PRIM)
    26. Chu trình và đường đi Euler
    27. Lab 7 - Tìm chu trình Euler
    28. Lab 7.1 - Tìm đường đi Euler
    29. Bài toán Luồng cực đại
    30. Lab 8 - Tìm luồng cực đại - sử dụng thuật toán Ford - Fulkerson
    31. Lab 8.1 - Tìm luồng cực đại - sử dụng thuật toán Edmonds - Karp (Shortest path)
  2. Tài liệu tham khảo 2
    1. Kho sách, nguồn tài liệu tham khảo Lập trình C++ - Cấu trúc dữ liệu và Giải thuật
    2. Bài tập Lý thuyết Đồ thị có lời giải
  3. Quy hoạch động 1
    1. Lý thuyết các bài toán sử dụng Quy hoạch động

Bài học trước Bài học tiếp theo