1. Trang chủ
  2. » Luận Văn - Báo Cáo

viết hàm có tên là dfsint u trên c c mô tả thuật toán duyệt theo chiều sâu

16 0 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Viết hàm có tên là DFS(int u) trên C/C++ mô tả thuật toán duyệt theo chiều sâu
Tác giả Đoàn Thị Trà My
Chuyên ngành Khoa học máy tính
Thể loại Bài tập
Định dạng
Số trang 16
Dung lượng 728,21 KB

Nội dung

void DFSint v{ cout... Viết hàm có tên là int TPLT_DFSint a[ ] [ ] trên C/C++ tìm số thành phần liên thông của đồ ị G = được biểu diễn dưới dạng ma trận kề a[ ] [ ] bằng thcách sử dụng

Trang 1

Họ tên: Đoàn Thị Trà My

MSV: B21DCAT134

Nhóm:

1 Viết hàm có tên là DFS(int u) trên C/C++ mô tả thuật toán duyệt theo chiều sâu các đỉnh của đồ thị G = <V, E> được biểu diễn dưới dạng ma trận kề a[ ] [ ]

void DFS(int v){

cout << v << " "; // tham dinh u

int u;

chuaxet[v]= 0; // danh dau la dinh v da duoc duyet

for(u=1; u<=n; u++){

if(a[v][u]==1 && chuaxet[u])

DFS(u);

}

}

Trang 2

2 Viết hàm có tên là BFS( int u) trên C/C++ mô tả uật toán duyệt theo chiều rộng các th đỉnh của đồ ị G = <V, E> được biểu diễn dưới dạng ma trận kề a[][] th

int n, u; // n đỉnh va duyet tu dinh u

int a[1000][1000] = {0};

bool visited[1000]; // v[i] = 1 -> đỉnh i đã được duyệt

int QUEUE[1000];

void BFS(int i){

int u,dauQ, cuoiQ;

dauQ=1; cuoiQ=1; QUEUE[cuoiQ]=i;

visited[i]= 1; // danh dau la da tham

/* thiết lập hàng đợi với đỉnh đầu là i*/

while(dauQ<=cuoiQ){

u=QUEUE[dauQ];// lấy đỉnh u ra ỏi queue.kh

cout<< u << " ";

dauQ=dauQ+1; /* duyệt đỉnh đầu hàng đợi*/

for(int j=1; j<=n;j++){

if(a[u][j]==1 && !visited[j]){

cuoiQ=cuoiQ+1;

QUEUE[cuoiQ]=j;

visited[j]=1;

}

}

}

}

Trang 3

3 Viết hàm có tên là int TPLT_DFS(int a[ ] [ ]) trên C/C++ tìm số thành phần liên thông của đồ ị G = <V, E> được biểu diễn dưới dạng ma trận kề a[ ] [ ] bằng th cách sử dụng hàm DFS(int u) đã biết mô tả thuật toán duyệt theo chiều sâu các đỉnh của đồ ị th G

int n, ans = 0; // n đỉnh và ans: số tplt của đồ thị

int a[1000][1000] = {0};

bool chuaxet[1000]; // ban đầu cho hết bằng 1 nghĩa là tất cả đỉnh chưa được duyệt

void DFS(int a[][1000], int n, int v, bool chuaxet[]){

int u;

chuaxet[v]= false;

for(u=1; u<=n; u++){

if(a[v][u]==1 && chuaxet[u])

DFS(a,n, u, chuaxet);

}

}

int TPLT_dfs(int a[][1000]){

ans = 0;

for(int i = 1; i<= n; i++){

if(chuaxet[i] == 1) {

ans++;

DFS(a, n, i, chuaxet);

}

}

return ans;

}

Trang 4

4 Viết hàm có tên là int TPLT_BFS(int a[ ] [ ]) trên C/C++ tìm số thành phần liên thông của đồ ị G = <V, E> th đư ợc biểu diễn dưới dạng ma trận kề a[ ] [ ] bằng cách sử dụng hàm BFS(int u) đã biết mô tả thuật toán duyệt theo chiều rộng các đỉnh của đồ ị th

G

int n, ans = 0; // n đỉnh và ans: số tplt của đồ thị

int a[1000][1000] = {0};

bool visited[1000]; // v[i] = 1 -> đỉnh i đã được duyệt

int QUEUE[1000];

void BFS(int i, bool visited[], int QUEUE[]){

int u,dauQ, cuoiQ;

dauQ=1; cuoiQ=1;QUEUE[cuoiQ]=i;

visited[i]= 1; // danh dau la da tham

/* thiết lập hàng đợi với đỉnh đầu là i*/

while(dauQ<=cuoiQ){

u=QUEUE[dauQ]; // lấy đỉnh u ra khỏi queue

dauQ=dauQ+1; /* duyệt đỉnh đầu hàng đợi*/

for(int j=1; j<=n;j++){

if(a[u][j]==1 && !visited[j]){

cuoiQ=cuoiQ+1;

QUEUE[cuoiQ]=j;

visited[j]=1;

}

}

}

}

int TPLT_bfs(int a[][1000]){

ans = 0;

for(int i = 1; i<= n; i++){

if(visited[i] == 0) {

ans++;

BFS(i, visited, QUEUE);

}

}

return ans;

}

Trang 5

5 Viết hàm có tên là T_DFS(int a[ ] [ ]) trên C/C++ tìm cây khung T[] của đồ ị th G

= <V, E> được biểu diễn dưới dạng ma trận kề a[][] bằng cách sử dụng hàm DFS(int u) đã biết mô tả thuật toán duyệt theo chiều sâu các đỉnh của đồ ị th G

int a[100][100], n, u, vs[100], e[100];

void Dfs(int u) {

int v;

vs[u]= 1;

for (v= 1; v<=n; v++)

if (vs[v]==0 && a[u][v]==1){

e[v]= u;

Dfs(v);

}

}

void T_Dfs(int a[][100]) {

int u =1; // lấy đỉnh đầu là 1;

int v;

for (v= 1; v<=n; v++) vs[v] = 0;

Dfs(u);

int dem= 0;

for (v= 1; v<=n; v++) if (vs[v] ==1) dem++;

if (dem == n) {

for (v= 1; v<=n; v++)

if (e[v] != 0) cout << e[v] << " "<< v << endl;

} else

cout << "Khong co Cay khung";

}

Trang 6

6 Viết hàm có tên là T_BFS(int a[ ] [ ]) trên C/C++ tìm cây khung T[] của đồ ị th G

= <V, E> được biểu diễn dưới dạng ma trận kề ][] bằng cách sử dụng hàm a[ BFS(int u) đã biết mô tả thuật toán duyệt theo chiều rộng các đỉnh của đồ thị G

const int MAX = 100; // giả sử số đỉnh của đồ ị là 100th

int n; // số đỉnh của đồ thị

int T[MAX]; // mảng lưu cây khung T

bool visited[MAX]; // mảng đánh dấu các đỉnh đã thăm

queue<int> Q; // hàng đợi lưu các đỉnh

void BFS(int u, int a[][MAX]){

visited[u] = true; // đánh dấu đỉnh u đã thăm

Q.push(u); // đưa u vào hàng đợi

while (!Q.empty()){

int v = Q.front(); // lấy đỉnh đầu tiên ra khỏi hàng đợi

Q.pop();

// duyệt các đỉnh kề v của đỉnh v

for (int i = 1; i <= n; i++){

if (a[v][i] > 0 && !visited[i]) {// nếu có cạnh (v, i) và đỉnh i chưa thăm

visited[i] = true; // đánh dấu đỉnh i đã thăm

Q.push(i); // đưa i vào hàng đợi

T[i] = v; // lưu đỉnh cha của i trong cây khung T

}

}

}

}

void T_BFS(int a[][MAX]){

memset(visited, false, sizeof(visited)); // ởi tạkh o m ảng visited toàn false

memset(T, 0, sizeof(T)); // khởi tạo mảng T toàn 0

BFS(1, a); // bắt đầu duyệt đồ ị từ đỉnh 1th

// hiển thị cây khung T

cout << "Cay khung T:" << endl;

for (int i = 2; i <= n; i++) { // bỏ qua đỉnh 1 vì là đỉnh bắt đầu của cây khung

cout << T[i] << "-" << i << endl;

}

}

Trang 7

7 Viết hàm có tên là EULER(int a[ ] [ ]) trên C/C++ tìm chu trình/đường đi Euler CE[ ] của đồ ị G = <V, E> được biểu diễn dưới dạng ma trận kề a[][], biết rằng th

G là đồ ị Euler/nửa Euler th

const int MAX = 1005;

int n;

int a[MAX][MAX];

vector<int> path;

void DFS(int u) {

for (int v = 1; v <= n; v++) {

if (a[u][v] != 0) {

a[u][v] =a[v][u]=0; // Xóa cạnh (u, v)

DFS(v);

}

}

path.push_back(u); // Thêm đỉnh u vào đường đi

}

vector<int> EULER(int a[][MAX]) {

// Tìm số đỉnh có bậc lẻ

int cnt = 0, start = 1;

for (int i = 1; i <= n; i++) {

int deg = 0;

for (int j = 1; j <= n; j++) {

deg += a[i][j];

}

if (deg % 2 != 0) {

cnt++;

start = i;

}

}

// Nếu số đỉnh có bậc lẻ lớn hơn 2, đồ ị không là đồ ị Euler th th

if (cnt > 2) {

cout << "Khong co chu trinh/duong di Euler!" << endl;

return vector<int>();

}

// Tạo stack S và đưa đỉnh start vào S

stack<int> S;

S.push(start);

Trang 8

// Duyệt đồ ị bằng thuật toán DFS và tìm chu trình Euler th while (!S.empty()) {

int u = S.top();

bool found = false;

for (int v = 1; v <= n && !found; v++) {

if (a[u][v] != 0) {

found = true;

S.push(v);

a[u][v] a[v][u]= 0= ; // Xóa cạnh (u, v) }

}

if (!found) {

S.pop();

path.push_back(u); // Thêm đỉnh u vào đường đi }

}

// Đảo ngược đường đi và trả về chu trình Euler vector<int> cycle(path.rbegin(), path.rend()); return cycle;

}

Trang 9

8 Viết hàm có tên là DIJKSTRA(int u) trên C/C++ tìm đư ờng đi ngắn nhất d[v] xuất phát từ đỉnh u đến các đỉnh v của đồ ị G = <V, E> được biểu diễn dướ th i dạng ma trận trọng số a[ ] [ ]

const int MAX = 1005; // giới hạn số đỉnh của đồ thị

int n; // số đỉnh của đồ thị

int a[MAX][MAX]; // ma trận trọng số của đồ thị

int d[MAX]; // mảng d[v] chứa độ dài đường đi ngắn nhất từ đỉnh u đến đỉnh v

bool visited[MAX]; // mảng visited để đánh dấu các đỉnh đã được duyệt trong thuật toán Dijkstra

void DIJKSTRA(int u) {

// Khởi tạo độ dài đường đi ngắn nhất từ đỉnh u đến các đỉnh v

for (int v = 1; v <= n; v++) {

d[v] = INT_MAX;

}

d[u] = 0;

// Tạo hàng đợi ưu tiên để lưu trữ các đỉnh và khoảng cách tương ứng

priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; pq.push(make_pair(0, u));

while (!pq.empty()) {

int du = pq.top().first;

int u = pq.top().second;

pq.pop();

if (visited[u]) {

continue;

}

visited[u] = true;

for (int v = 1; v <= n; v++) {

if (a[u][v] != 0 && !visited[v]) {

if (d[v] > du + a[u][v]) {

d[v] = du + a[u][v];

pq.push(make_pair(d[v], v));

}

}

}

}

}

Trang 10

9 Viết hàm có tên là FLOYD(int a[ ] [ ]) trên C/C++ tìm đường đi ngắn nhất d[ ] [ ] giữa các cặp đỉnh của đồ ị G = <V, E> được biểu diễn dưới dạng ma trận trọng th

số a[ ] [ ]

const int INF = 1e9; // Giá trị vô cùng

const int MAXN = 1005;

void FLOYD(int a[][MAXN], int d[][MAXN], int n) {

// Khởi tạo ma trận đường đi

for (int i = 1; i <= n; i++) {

for (int j = 1; j <= n; j++) {

d[i][j] = a[i][j];

}

}

// Duyệt qua tất cả các đỉnh trung gian

for (int k = 1; k <= n; k++) {

// Duyệt qua tất cả các cặp đỉnh (i, j)

for (int i = 1; i <= n; i++) {

for (int j = 1; j <= n; j++) {

// Nếu tồn tại đường đi ngắn hơn từ i đến j đi qua đỉnh k

if (d[i][k] < INF && d[k][j] < INF && d[i][j] > d[i][k] + d[k][j]) { // Cập nhật giá trị đường đi ngắn nhất từ i đến j

d[i][j] = d[i][k] + d[k][j];

}

}

}

}

}

Trang 11

10 Viết hàm có tên là PRIM(int a[ ] [ ], int u) trên C/C++ tìm cây khung T[ ] nhỏ nhất bắt đầu tại đỉnh u của đồ ị G = <V, E> được biểu diễn dưới dạng ma trậ th n trọng số a[ ] [ ] bằng cách sử dụng thuật toán Prim

const int INF = 1e9;

const int MAX = 1000;

int PRIM(int a[MAX][MAX], int u) {

int V = sizeof(a[0])/sizeof(a[0][0]); // lấy số đỉnh của đồ thị

int key[V]; // key[i] lưu giá trị nhỏ nhất để đi từ T đến i

int parent[V]; // lưu cây khung nhỏ nhất đã tìm được

bool mstSet[V]; // mstSet[i] = true nếu đỉnh i đã được đưa vào cây khung nhỏ nhất

// khởi tạo giá trị cho key và mstSet

for (int i = 0; i < V; i++) {

key[i] = INF;

mstSet[i] = false;

}

key[u] = 0; // giá trị key của đỉnh xuất phát bằng 0

parent[u] = -1; // đỉnh xuất phát không có parent

for (int count = 0; count < V - 1; count++) {

// Tìm đỉnh có key nhỏ nhất chưa được chọn vào cây khung nhỏ nhất

int minKey = INF, minIndex;

for (int v = 0; v < V; v++) {

if (mstSet[v] == false && key[v] < minKey) {

minKey = key[v];

minIndex = v;

}

}

// Thêm đỉnh đã tìm được vào cây khung nhỏ nhất

mstSet[minIndex] = true;

// Cập nhật giá trị key và parent của các đỉnh kề với đỉnh đã thêm vào cây khung nhỏ nhất for (int v = 0; v < V; v++) {

if (a[minIndex][v] && mstSet[v] == false && a[minIndex][v] < key[v]) { parent[v] = minIndex;

key[v] = a[minIndex][v];

}

}

}

// In cây khung nhỏ ất tìm được nh

cout << "Cay khung nho nhat:\n";

for (int i = 0; i < V; i++) {

if (parent[i] != -1) {

cout << parent[i] << " - " << i << " " << a[i][parent[i]] << "\n";

}

}

}

Trang 12

11 Viết hàm có tên là KRUSKAL(int a[ ] [ ]) trên C/C++ tìm cây khung T[ ] nhỏ nhất của đồ ị G = <V, E> được biểu diễn dưới dạng ma trận trọng số a[ ] [ ] th bằng cách sử dụng thuật toán Kruskal

int n, m;

const int MAXN = 100;

int parent[MAXN];

int sz[MAXN];

struct Edge {

int u, v, w; //u: đỉnh đầu ; v: đỉnh cuối; w: trọng số

};

void make_set(){

for (int i= 1; i<= n; i++){

parent[i] = i;

sz[i] = 1;

}

}

int find(int v){

if( v== parent[v]) return v;

return parent[v] = find(parent[v]);

}

bool merge(int x, int y) {

x = find(x);

y = find(y);

if(x== y) return 0; // ko the gop x, y vao voi nhau

if (sz[x] < sz[y]) swap(x, y);

parent[y] = x;

sz[x] += sz[y];

return true;

}

vector<Edge> canh;

void inp(){ // input

cin >> n >> m;

for(int i = 0; i < m ; i++){

int x, y, w; cin>> x >> y >> w;

Edge e ;

e.u = x; e.v = y; e.w = w;

canh.push_back(e);

}

}

Trang 13

bool cmp(Edge a, Edge b) {

return a.w < b.w;

}

void kruskal(){

// Tao cay khung

vector<Edge> mst;

int d = 0;

// sort danh sach canh theo chieu dai tang dan

sort(canh.begin(), canh.end(), cmp);

// lap

for(int i = 0; i< m; i++){

if(mst.size() == n-1) break;

Edge e = canh[i]; // chon e la canh nho nhat

if(merge(e.u, e.v)){

mst.push_back(e);

d+= e.w;

}

}

// tra ve ket qua

if(mst.size() != n-1){

cout << "Do thi khong lien thong" << endl;

}

else{

cout << "Do dai cuc tieu cua cay khung: " << d << endl; for (auto it : mst) {

cout << it.u << " " << it.v << " " << it.w << endl; }

}

}

Trang 14

12 Viết chương trình hoàn chỉ nh tìm luồng cực đại f[][] trên mạng G = <V, E> đượ c biểu diễn dưới dạng ma trận trọng số c[ ] [ ] với đỉnh phát s và đỉnh thu t bằng cách sử dụng thuật toán đường tăng luồ ng dựa trên Ford-Fulkerson :

Yêu cầu :

(1) Nhập ma trận trọng số ểu diễn G từ tệp DT.INP ; với s= 1 ; t= n bi ;

(2) Tìm luồng cực đại f ;

(3) Xuất kết quả ra tệp DT.OUT :

- Dòng đầu ghi Val(f) ;

- N dòng sau ghi f[i][j] ;

#include <bits/stdc++.h>

#include <cstring>

#include <queue>

#include <limits.h>

#define MAX 100

using namespace std;

int n, s = 1, t; // đỉnh phát s = 1

int c[MAX][MAX], f[MAX][MAX], trace[MAX];

int res = 0; // giá trị ồng cực đạilu

bool bfs() { // tìm đường tăng luồng bằng BFS

queue<int> q;

q.push(s);

memset(trace, 0, sizeof(trace)); // khởi tạo trace

trace[s] = s;

while (!q.empty()) {

int u = q.front(); q.pop();

for (int v = 1; v <= n; v++) {

if (trace[v] == 0 && f[u][v] < c[u][v]) {

Trang 15

q.push(v);

trace[v] = u;

if (v == t) return true;

}

}

}

return false;

}

void augment_path() { // cập nhật luồng trên đường tăng luồng int u = t, v;

int delta = INT_MAX;

while (u != s) {

v = trace[u];

delta = min(delta, c[v][u] - f[v][u]);

u = v;

}

u = t;

while (u != s) {

v = trace[u];

f[v][u] += delta;

f[u][v] -= delta;

u = v;

}

res += delta; // cập nhật giá trị ồng cực đạilu

}

void ford_fulkerson() { // thuật toán Ford-Fulkerson while (bfs()) {

augment_path();

Ngày đăng: 16/08/2024, 17:35

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w