Archive | Ngôn ngữ C++
RSS for this section
[C++] Tìm chu trình Euler
Tác giả:
- Trần Hán Huy – tranhanhuy.wordpress.com
Đề bài
- Cho G=(X,E) là một đồ thị liên thông vô hướng gồm n đỉnh. Hãy tìm chu trình Euler
Lý thuyết
- CHU TRÌNH Euler: dây chuyền đi qua tất cả các cạnh của đồ thị, mỗi cạnh đúng một lần và đỉnh bắt đầu đi trùng với đỉnh kết thúc
Code chỉ giải quyết
- Dùng tham số dòng lệnh với tập tin input
- Đầu vào input : là ma trận kề
- Do là ma trận kề nên ko thể hiện được cạnh song song và khuyên : mặt hạn chế
- yêu cầu đưa vào là 1 đồ thị Euler
- Chỉ giải quyết 1 đồ thị Euler
- Đầu vào là file input, đầu xuất là màn hình
- Sử dụng stack để giải quyết vấn đề
- Chỉ xuất ra 1 chu trình Euler
- vào ma trận kề nhưng được chuyển qua thành danh sách cạnh đầy đủ: tức 1 cạnh được lặp 2 lần. UV và VU
Code tìm chu trình Euler
void Euler::TimChuTrinh() { //tao 1 stack vector<Canh> stack; //Cạnh tạm bằng cạnh đầu tiên trong dscanh Canh tam = m_DsCanh[0]; //Xóa cạnh bắt đầu m_DsCanh.erase(m_DsCanh.begin() + 0); //đưa cạnh đầu tiên vào stack stack.push_back(tam); //Kiểm tra số lượng stack while (stack.size()>0) { //lấy cạnh cuối cùng trong stack tam = stack[stack.size()-1]; //xóa cạnh giống với tam: tam là UV thì xóa đi VU for (int i = 0; i < (signed)m_DsCanh.size(); i++) { if (m_DsCanh[i].SoSanhDinh1(tam.getDinh2()) && m_DsCanh[i].SoSanhDinh2(tam.getDinh1())) //xoa cạnh VU m_DsCanh.erase(m_DsCanh.begin() + i); } //cờ để đánh dấu có cạnh kề với đỉnh 2 của cạnh tạm ko? bool flag = false; //Tìm cạnh kề đầu tiên với đỉnh 2 của cạnh tạm for (int i = 0; i < (signed)m_DsCanh.size(); i++) { //tìm cạnh tiếp theo có đỉnh đầu là đỉnh 2 của cạnh tạm if (m_DsCanh[i].SoSanhDinh1(tam.getDinh2())) { //lấy cạnh i ra tam = m_DsCanh[i]; //đưa vào stack stack.push_back(tam); //xóa cạnh i ra dsCanh m_DsCanh.erase(m_DsCanh.begin() + i); //bật cờ flag = true; //thoát ra vòng for break; } } //không có cạnh kề if (!flag) { //tiến hành lấy cạnh tạm nhưng đảo ngược đỉnh đầu cuối Canh t(tam.getDinh2(), tam.getDinh1()); //đưa vào chu trinh euler m_ChuTrinh.push_back(t); //xóa cạnh tam ra khỏi stack stack.pop_back();//vì tam là cạnh cuối của stack nên chỉ popback đc rồi } } }
Link source:
[C++] Tìm tất cả đồ thị con của các thành phần liên thông trong đồ thị G
Tác giả:
- Trần Hán Huy – tranhanhuy.wordpress.com
Đề bài
- Cho G=(X,E) là một đồ thị gồm n đỉnh. Hãy tìm tất cả đồ thị con của đồ thị G liên thông
Code áp dụng
- đối tượng
- Giải quyết nhiều liên thông
- Main sử dụng tham số dòng lệnh
- Nhập từ tập tin và chỉ xuất ra màn hình để xem kết quả (ko xuất ra tập tin)
- Xuất theo thứ tự từ liên thông nhỏ đến lớn , đồ thị con nhỏ nhất đến đồ thị con lớn nhất 🙂
Input trong source kèm theo là hình sau:
Ý tượng trong code
void DoThiCon :: XuatDoThiCon() { //Tim chieu dai theo thu tu tang dan for (int L=1; L<=(signed) m_DinhLienThong.size(); L++) { //duyet tung dinh cua DinhLienThong for (int j=0; j<(signed) m_DinhLienThong.size(); j++) { vector<int> DsDinh ; DsDinh.push_back(m_DinhLienThong[j]); XuatDoThiConTheoL(m_DinhLienThong[j], L, DsDinh); } } } void DoThiCon::XuatDoThiConTheoL(int DinhX, int L, vector<int> DsDinh) { if (DsDinh.size()==L) { XuatDoThiConTimDuoc(DsDinh); return; } //duyet tung dinh ke co gia tri lon hon dinh X for (int i=DinhX + 1; i<(signed)m_MaTranKe.size(); i++) { if (m_MaTranKe[DinhX][i] != 0) { DsDinh.push_back(i); //dua vao Ds Dinh XuatDoThiConTheoL(i, L, DsDinh); DsDinh.pop_back(); //Lay ra khoi Ds Dinh } } }
Link source:
[C++] Tìm đỉnh gốc của đồ thị G có hướng
Tác giả:
- Trần Hán Huy – tranhanhuy.wordpress.com
Đề bài
- Cho G=(X,E) là một đồ thị có hướng có trọng số gồm n đỉnh. Hãy tìm Gốc của đồ thị G có hướng
Lý thuyết
- Đồ thị có hướng: có thể có nhiều đỉnh gốc
- Cây có hướng: chỉ tồn tại duy nhất 1 đỉnh gốc
- Đỉnh gốc là từ đỉnh đó có thể đi hết tất cả các đỉnh trong đồ thị có hướng và liên thông
Code áp dụng
- đối tượng
- Giải quyết nhiều đồ thị có hướng và liên thông
- Main sử dụng tham số dòng lệnh
- Có thể sửa lại ở main cách nhập ma trận kề từ bàn phím hay tập tin
- Tìm ra nhiều gốc của đồ thị G có hướng
Input1 trong source kèm theo là hình sau:
Ý tượng trong code
void Goc::TimGoc() { //duyet qua tat ca cac dinh cua do thi lien thong for (int i=0; i<(signed)m_DinhLienThong.size(); i++) { m_DinhGoc = m_DinhLienThong[i]; vector<int> DsDinh; DsDinh.push_back(m_DinhGoc); if (TimGocTuX(m_DinhGoc, DsDinh)) { cout << m_DinhGoc << endl; } } } bool Goc::TimGocTuX(int x, vector<int> &DsDinh) { //kiem tra dieu kien dung if (DsDinh.size() == m_DinhLienThong.size()) return true; //duyet qua tung dinh noi voi X for (int i=0; i<(signed)m_MaTranKe[x].size(); i++) { //Canh XI ton tai va chua di qua if (m_MaTranKe[x][i] != 0 && !KiemTraXDiChua(i, DsDinh)) { //Dua I vao DSDinh DsDinh.push_back(i); //tu I di tim duong di cac dinh khac if (TimGocTuX(i,DsDinh)) return true; } } return false; }
Link source:
[C++] Tìm tất cả chu trình Hamilton
Tác giả:
- Trần Hán Huy – tranhanhuy.wordpress.com
Đề bài
- Cho G=(X,E) là một đồ thị liên thông có trọng số gồm n đỉnh. Hãy tìm Tất cả chu trình Hamilton
Lý thuyết
- CHU TRÌNH HAMILTON: dây chuyền đi qua tất cả các đỉnh của đồ thị mỗi đỉnh đúng một lần và một cạnh trong đồ thị nối đỉnh đầu của dây chuyền với đỉnh cuối của nó
Thuật toán
- Tới thời điểm này thì vẫn chư có 1 thuật toán tối ưu nào để áp dụng.
- Đoạn code dưới sử dụng thuật toán đệ qui quay lùi
Ý tượng tìm 1 chu trình Hamilton
Thuật toán đệ quy quay lùi thực hiện các bước sau:
- B1: đưa đỉnh x vào đường đi
- B2: kiểm tra chu trình đủ chiều dài chưa? (tức là đã đi hết tất cả các đỉnh chưa?) và đồng thời kiểm tra đình đầu và đỉnh cuối của chu trình có cạnh nối hay ko? Nếu true hết cả 2 điều kiện thì kết luận có chu trình Hamilton. Ngược lại gọi B3
- B3: Duyệt hết tất cả các đỉnh kề với x
- B4: Kiểm tra đỉnh kề đã đi qua chưa? Nếu true gọi lại hàm đệ qui tìm chu trình Hamilton
- B5: Xóa đỉnh kề ra khỏi chu trình
Link source:
[C++] Tìm 1 chu trình Hamilton
Tác giả:
- Trần Hán Huy – tranhanhuy.wordpress.com
Đề bài
- Cho G=(X,E) là một đồ thị liên thông có trọng số gồm n đỉnh. Hãy tìm Một chu trình Hamilton
Lý thuyết
- CHU TRÌNH HAMILTON: dây chuyền đi qua tất cả các đỉnh của đồ thị mỗi đỉnh đúng một lần và một cạnh trong đồ thị nối đỉnh đầu của dây chuyền với đỉnh cuối của nó
Thuật toán
- Tới thời điểm này thì vẫn chư có 1 thuật toán tối ưu nào để áp dụng.
- Đoạn code dưới sử dụng thuật toán đệ qui quay lùi
Ý tượng tìm 1 chu trình Hamilton
Thuật toán đệ quy quay lùi thực hiện các bước sau:
- B1: đưa đỉnh x vào đường đi
- B2: kiểm tra chu trình đủ chiều dài chưa? (tức là đã đi hết tất cả các đỉnh chưa?) và đồng thời kiểm tra đình đầu và đỉnh cuối của chu trình có cạnh nối hay ko? Nếu true hết cả 2 điều kiện thì kết luận có chu trình Hamilton. Ngược lại gọi B3
- B3: Duyệt hết tất cả các đỉnh kề với x
- B4: Kiểm tra đỉnh kề đã đi qua chưa? Nếu true gọi lại hàm đệ qui tìm chu trình Hamilton
- B5: Xóa đỉnh kề ra khỏi chu trình
Link source: