Tải bản đầy đủ (.docx) (12 trang)

Bài thảo luận tìm thành phần liên thông của đồ thị

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (295.19 KB, 12 trang )

I. Các khái niệm:
1. Đồ thị:
- Đồ thị là một cấu trúc rời rạc gồm các đỉnh và các cạnh nối các đỉnh đó. Được
mô tả hình thức: G = (V, E)
+ V gọi là tập các đỉnh (Vertices)
+ E gọi là tập các cạnh (Edges). Có thể coi E là tập các cặp (u, v) với u và v là
hai đỉnh của V.
- Có thể phân loại đồ thị theo đặc tính và số lượng của tập các cạnh E:
Cho đồ thị G = (V, E). Định nghĩa một cách hình thức
+ G được gọi là đơn đồ thị nếu giữa hai đỉnh u, v của V có nhiều nhất là 1 cạnh
trong E nối từ u tới v.
+ G được gọi là đa đồ thị nếu giữa hai đỉnh u, v của V có thể có nhiều hơn 1
cạnh trong E nối từ u tới v (Hiển nhiên đơn đồ thị cũng là đa đồ thị).
+ G được gọi là đồ thị vô hướng nếu các cạnh trong E là không định hướng, tức
là cạnh nối hai đỉnh u, v bất kỳ cũng là cạnh nối hai đỉnh v, u. Hay nói cách khác,
tập E gồm các cặp (u, v) không tính thứ tự. (u, v)≡(v, u)
+ G được gọi là đồ thị có hướng nếu các cạnh trong E là có định hướng, có thể
có cạnh nối từ đỉnh u tới đỉnh v nhưng chưa chắc đã có cạnh nối từ đỉnh v tới đỉnh
u. Hay nói cách khác, tập E gồm các cặp (u, v) có tính thứ tự: (u, v) ≠ (v, u). Trong
đồ thị có hướng, các cạnh được gọi là các cung. Đồ thị vô hướng cũng có thể coi
là đồ thị có hướng nếu như ta coi cạnh nối hai đỉnh u, v bất kỳ tương đương với
hai cung (u, v) và (v, u).
- Cạnh liên thuộc, đỉnh kề, bậc
+ Đối với đồ thị vô hướng G = (V, E). Xét một cạnh e ∈ E, nếu e = (u, v) thì ta
nói hai đỉnh u và v là kề nhau (adjacent) và cạnh e này liên thuộc (incident) với
đỉnh u và đỉnh v.
+ Với một đỉnh v trong đồ thị, ta định nghĩa bậc (degree) của v, ký hiệu deg(v)
là số cạnh liên thuộc với v. Dễ thấy rằng trên đơn đồ thị thì số cạnh liên thuộc với
v cũng là số đỉnh kề với v.
TRƯỜNG ĐẠI HỌC THƯƠNG MẠI
KHOA: HỆ THỐNG THÔNG TIN KINH TẾ


BÀI THẢO LUẬN
Môn: Cấu trúc dữ liệu và giải thuật
Đề tài : Tìm thành phần liên thông
LỚP HỌC PHẦN: 1402INFO1311
SINH VIÊN: Nguyễn Quang Nghĩa
GIÁO VIÊN HƯỚNG DẪN: Thầy Cù Nguyên Giáp
2. Thành phần liên thông:
- Đối với đồ thị vô hướng:
G gọi là liên thông (connected) nếu luôn tồn tại đường đi giữa mọi cặp đỉnh
phân biệt của đồ thị.
Nếu G không liên thông thì chắc chắn nó sẽ là hợp của hai hay nhiều đồ thị con
liên thông, các đồ thị con này đôi một không có đỉnh chung. Các đồ thị con liên
thông rời nhau như vậy được gọi là các thành phần liên thông của đồ thị đang xét.
- Đối với đồ thị vô hướng:
G gọi là liên thông mạnh nếu luôn tồn tại đường đi (theo các cung định hướng)
giữa hai đỉnh bất kỳ của đồ thị, G gọi là liên thông yếu nếu đồ thị vô hướng nền
của nó là liên thông
II. Tư tưởng và các bước của thuật toán:
- Giả sử đồ thị vô hướng G = (V, E) có n đỉnh đánh số 1, 2, , n.
- Để liệt kê các thành phần liên thông của G phương pháp cơ bản nhất là:
+ Đánh dấu đỉnh 1 và những đỉnh có thể đến từ 1, thông báo những đỉnh đó
thuộc thành phần liên thông thứ nhất.
+ Nếu tất cả các đỉnh đều đã bị đánh dấu thì G là đồ thị liên thông, nếu không
thì sẽ tồn tại một đỉnh v nào đó chưa bị đánh dấu, ta sẽ đánh dấu v và các đỉnh có
thể đến được từ v, thông báo những đỉnh đó thuộc thành phần liên thông thứ hai.
+ Và cứ tiếp tục như vậy cho tới khi tất cả các đỉnh đều đã bị đánh dấu.
procedure Duyệt(u)
begin
< Dùng BFS hoặc DFS liệt kê và đánh dấu những đỉnh có thể đến được từ u >
end;

begin
for ∀ v ∈ V do < khởi tạo v chưa đánh dấu >;
Count := 0;
for u := 1 to n do
if < u chưa đánh dấu > then
begin
Count := Count + 1;
WriteLn('Thành phần liên thông thứ ', Count, ' gồm các đỉnh : ');
Duyệt(u);
end;
end.
III. Đánh giá độ phức tạp của thuật toán:
- Với thuật toán liệt kê các thành phần liên thông như thế này, thì độ phức tạp tính
toán của nó đúng bằng độ phức tạp tính toán của thuật toán tìm kiếm trên đồ thị
trong thủ tục Duyệt.
- Trước hết nhận thấy rằng số phép toán cần thực hiện trong hai chu trình của
thuật toán( hai vòng for của chương trình chính) là cỡ n. Thủ tục phải thực hiện
không quá n lần. Tổng số phép toán cần phải thực hiện trong các thủ tục này là
O(n+m), do trong các thủ tục này ta phải xét qua tất cả các cạnh và các đỉnh của
đồ thị. Vậy độ phức tạp tính toán của thuật toán là O(n+m). ( với n là số đỉnh, m là
số cạnh )
IV. Chương trình minh họa:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define max 50
typedef struct node
{
int dinhke;
int weight;

struct node *next;
}node;
typedef struct dothi
{
node* dinh[max];
int n;
}dothi;
int m, *label, sotp;
dothi G;
char tep[20];
// khai báo prototype
void insert(int , int , int);
int getdata();
void print();
void Visit(int , int *);
int findConnected();
//ham main
int main()
{
int dem;
for(int i=0; i<m; i++)
G.dinh[i] = NULL;
if(getdata())
{
print();
dem = findConnected();
printf("\n\n so thanh phan lien thong la %d\n", dem);
}
else
printf("\n Tep %s khong mo duoc ", tep);

/////////////////
getch();
return 0;
}
// ham them dinh ke
void insert(int u, int v, int w)
{
if(G.n> u && G.n> v) // neu u va v nho hon so dinh toi da
{
if(G.dinh[u]!= NULL) // neu tk khong rong
{
node * tk = G.dinh[u];
node * tk1;
while(tk !=NULL)
{
if(tk->dinhke == v) break; // neu dinh v da co thi thoat ra
else
{
tk1 = tk;
tk = tk->next;
}
}
if(tk == NULL)
{
tk = (node*)malloc(sizeof(node));
tk->dinhke = v;
tk->weight = w;
tk->next = NULL;
tk1->next = tk;
}

}
else
{
G.dinh[u] = (node*)malloc(sizeof(node));
G.dinh[u]->dinhke = v;
G.dinh[u]->weight = w;
G.dinh[u]->next = NULL;
}
}
}
/*Ðoc file du lieu*/
int getdata()
{
printf("\n NHAP TEN TEP: ");
gets(tep);
FILE* f = fopen(tep,"r"); // mo file
if(f == NULL) // neu ko mo dc
return 0;
else
{
int i, j, k;
fscanf(f,"%d",&m); // doc so dinh
G.n = m;
while(!feof(f)) // khi chua ket thuc tep
{
fscanf(f,"%d, %d, %d",&i, &j, &k);
insert(i,j,k);
insert(j,i,k);
}
fclose(f);

return 1;
}
}
/* ham in danh sach ke */
void print()
{
printf("\n Danh sach dinh ke:\n");
for(int i=0; i<m; i++)
{
printf("\nCac dinh ke voi dinh %d: ", i);
if(G.dinh[i] == NULL) continue;
node *tk= G.dinh[i];
//node* tk1;
while(tk->next!= NULL)
{
printf("%d, ", tk->dinhke);
tk = tk->next;
}
printf("%d", tk->dinhke);
}
}
// ham tim so thanh phan lien thong
int findConnected()
{
label = (int*)malloc(m*sizeof(int));
for(int i = 0; i < m; i++)
label[i] = 0;
sotp = 0;
for(int i = 0; i < m; i++)
{

if(label[i] == 0)
{
sotp++;
Visit(i, label);
}
}
return sotp;
}
// ham duyet dinh
void Visit(int i, int *label)
{
label[i] = sotp;
node *tk = G.dinh[i];
while(tk!=NULL)
{
if(label[tk->dinhke] == 0)
Visit(tk->dinhke, label);
else tk = tk->next;
}
}
- Kết quả chạy với file dulieu01.txt:
- Kết quả chạy với file dulieu02.txt:
- Kết quả chạy với file dulieu03.txt:
- Kết quả chạy với file dulieu04.txt:
- Kết quả chạy với file dulieu05.txt:

×