Mô tả bài toán: cho đồ thị vô hướng có trọng số G=(V,E) hãy tìm đường đi sao cho tất cả các đỉnh điều có đường đi với nhau và tổng trọng số của đường đi là nhỏ nhất.
Ý tưởng thuật toán:
Bước 1: xuất phát từ đỉnh k bất kỳ (thông thường chọn đỉnh đầu tiên) chọn một cạnh có trọng số nhỏ nhất liền kề với đỉnh k (min{A[k][j]}j=1..n) ta đánh dấu 2 đỉnh đi qua cạnh đó và số cạnh tìm được là 1. Chuyển sang Bước 2.
Bước 2: tìm cạnh nhỏ nhất của đồ thị với điều kiện cạnh tìm được phải có 1 đỉnh chưa đánh dấu và 1 đỉnh đã đánh dấu. Nghĩa là, ta tìm min{A[i][j]} j=1..n, i=1..n sao cho i đánh dấu và j chưa đánh dấu để tránh trường hợp tạo thành chu trình con. Ta tăng số cạnh tìm được lên 1 và chuyển sang Bước 3.
Bước 3: nếu số cạnh tìm được bằng n-1 kết thúc thuật toán, ngược lại quay về Bước 2.
Mô tả dữ liệu đầu vào và đầu ra của bài toán:
Dữ liệu vào: lưu trong tập tin Bai7.inp
- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100)
- Dòng i+1 (1<=i<=n) lưu ma trận kề của đồ thị với n số A[i,1], A[i,2],…, A[i,n] mỗi số cách nhau bởi một khoảng trắng.
Dữ liệu ra: lưu trong file Bai7.out
- Dòng đầu ghi trọng số nhỏ nhất của cây bao trùm.
- Các dòng còn lại lưu đường đi giữa đỉnh i nối với đỉnh j.
Ví dụ:
Cài đặt chương trình:
#include <stdio.h>
#include <values.h>
#define max 100
#define FileInt "Bai7.inp"
#define FileOut "Bai7.out"
typedef struct Egde{
int x,y;
};
//đọc dữ liệu từ tập tin
void Doc_File(int A[max][max],int &n) {
FILE*f = fopen(FileInt,”rb”);
fscanf(f,”%d”,&n);
for(int i =0;i<n;i++) {
for(int j =0;j<n;j++) {
fscanf(f,”%d”,&A[i][j]);
}
}
fclose(f);
}
//ghi dữ liệu ra tập tin
void Ghi_File(Egde L[max],int n,int Sum) {
FILE*f = fopen(FileOut,"wb");
fprintf(f,"%d\n",Sum);
for(int i =0; i<n-1; i++)
fprintf(f,"%d -%d\n",L[i].x+1,L[i].y+1);
fclose(f);
}
//thuật toán Prim
void Prim(int A[max][max], int n) {
char D[max];
Egde L[max];
int min = MAXINT, Dem = 0, Sum = 0;
for(int i=0; i<n; i++)
D[i]=0;
for(int j=1; j<n; j++)
if(min>A[0][j] && A[0][j]!=0){
min = A[0][j];
L[0].y = j;
}
L[0].x = 0;
D[0] = 1;
D[L[0].y] = 1;
Sum+=min;
Dem++;
do {
min = MAXINT;
for( i=0; i<n; i++)
if(D[i]==1)
for( j=0; j<n; j++)
if(A[i][j]>0 && min>A[i][j] && D[j]==0){
min = A[i][j];
L[Dem].x = i;
L[Dem].y = j;
}
Sum+=min;
D[L[Dem].y] = 1;
Dem++;
} while(Dem<n-1);
Ghi_File(L,n,Sum);
}
//chương trình chính
void main() {
int A[max][max],n;
Doc_File(A,n);
Prim(A,n);
}
Tags: Kỹ thuật lập trình, toán rời rạc, c, c++, prim, cây khung
Related Post:
Bai Tap On Java Nag Cao ^_^Bai Tap On Java Nag Cao… Read More
Java EE 7 hỗ trợ điện toán mây Oracle cho biết phiên bản mới của Java EE vào năm 2012 sẽ có nhiều yếu tố phù hợp trên nền điện toán đám mây và đồng thời cũng có tương thích với REST.Oracle hiện đang phát triển phiên bản Java kế tiếp hướng đến doanh nghiệp, trong đó sẽ có những cải tiến đáng kể liên quan đến điện toán mây, webservice theo phương pháp REST và một số tương thích khác.Aja… Read More
Tự xây dựng 1 security frameworkXây dựng security cho một ứng dụng phần mềm gần như là một yêu cầu bắt buộc đối với tất cả các hệ thống phần mềm. Phân hệ security này có hai nhiệm vụ chính: a) kiểm tra xem người dùng đăng nhập có cung cấp đúng username và password không b) nếu đúng thì kiểm tra người dùng đã đăng nhập có quyền cập nhật, xóa hoặc xem một tài nguyên (địa chỉ url, file, phương th… Read More
Tự xây dựng một framework lập trình hướng khía cạnh (AOP)Lập trình khía cạnh là gì?Sự xuất hiện của ngôn ngữ hướng đối tượng là một cuộc cách mạng trong lĩnh vực phần mềm. Nhiều người đánh giá nếu không có phương pháp phân tích và thiết kế hướng đối tượng, ngành công nghiệp phần mềm sẽ rơi vào khủng hoảng bởi sự phức tạp ngày càng gia tăng trong các hệ thống phần mềm. May mắn thay điều đó đã không xảy ra. Sau hơn 30 nă… Read More
Các thuật toán hay và khó Bàn thêm về thuật toán floyd-warshall (Thầy Trần Thông Quế) Để các bạn học sinh và sinh viên mới bắt đầu nghiên cứu hoặc học “Lý thuyết đồ thị” dễ nhận thức hơn về thuật toán này tôi sẽ nói chi tiết về nó và cung cấp cho các bạn một cài đặt trực quan. 1. Mục đích của Floyd-Warshall Algorithm (viết tắt là F-W Algo.) là tìm đường đi ngắn nhất giữa mọi cặp đỉnh trên đ… Read More
Tự xây dựng 1 framework đảo ngược điều khiển (IoC - Inversion of Control)1. Nguyên lý đảo ngược điều khiểnSự ra đời của Spring như là một chọn lựa khác cho EJB đã đánh dấu một bước ngoặt trong lịch sử phát triển của Enterprise Java. Theo thời gian Spring không ngừng được mở rộng với ngày càng nhiều tính năng mới. Tuy vậy, một trong những phần chủ chốt của Spring vẫn là IoC container. Đảo ngược điều khiển là một nguyên lý (hay design pa… Read More
Klik untuk melihat kode: