More Related Content
More from Nguyễn Công Hoàng (14)
Kruskal algorithm
- 1. // File: Kruskal.h-------------------------------------------------------------
#ifndef _MY_KGRAPH_H
#define _MY_KGRAPH_H
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
class Edge {
int v1, v2;
float w;
public:
Edge(int v1=0, int v2=0, float w=0);
int getV1();
int getV2();
float getW();
ostream& Show(ostream& outDev) const;
friend bool operator < (const Edge& e1, const Edge& e2);
friend bool operator == (const Edge& e1, const Edge& e2);
friend istream& operator >> (istream&, Edge&);
friend ostream& operator << (ostream&, const Edge&);
};
class KruskalAlgo {
vector<int> Label;
vector<Edge> Edges;
vector<Edge> T;
int nVer;
void UpdateLabels(int v1, int v2);
void InitAlg();
public:
void LoadEdges(istream& inDev) ;
bool LoadEdges(char* fName) ;
int RunAlg();
void ShowT(ostream& outDev);
};
#endif
// end of File: Kruskal.h-------------------------------------------------------
- 2. // File Kruskal.cpp-----------------------------------
#include "Kruskal.h"
// Methods and operators for Edge class
Edge::Edge(int v1, int v2, float w){
this->w=w;
this->v1=v1;
this->v2=v2;
}
int Edge::getV1() {
return v1;
}
int Edge::getV2() {
return v2;
}
float Edge::getW() {
return w;
}
ostream& Edge::Show(ostream& outDev) const {
outDev << v1 << "----"<< v2 << " ; w = " << w;
return outDev;
}
bool operator < (const Edge& e1, const Edge& e2){
return e1.w < e2.w;
}
bool operator == (const Edge& e1, const Edge& e2){
return e1.w == e2.w;
}
istream& operator >> (istream& inDev, Edge& e){
inDev >> e.v1 >> e.v2 >> e.w;
return inDev;
}
ostream& operator << (ostream& outDev, const Edge& e){
return e.Show(outDev);
}
- 3. // Methods and operators for KruskalAlgo class
void KruskalAlgo::LoadEdges(istream& inDev)
{
int nE;
Edge e;
inDev >> nVer >> nE;
for (int i=0; i<nE; i++){
inDev >> e;
Edges.push_back(e);
}
}
bool KruskalAlgo::LoadEdges(char* fName)
{
ifstream inFile(fName);
if (inFile){
LoadEdges(inFile);
return true;
}
return false;
}
void KruskalAlgo::UpdateLabels(int v1, int v2)
{
if (v1<0 || v1 >= nVer || v2<0 || v2>=nVer){
return;
}
int minLabel = Label[v1], maxLabel = Label[v2];
if (minLabel > Label[v2]){
minLabel = Label[v2];
maxLabel = Label[v1];
}
for (int i=0; i<nVer; i++)
if (Label[i] == maxLabel){
Label[i] = minLabel;
}
}
/* LƯU Ý: Ghi nhận đoạn mã sai sau đây đế rút kinh nghiệm:
if (Label[v1] < Label[v2]){
for (int i=0; i<nVer; i++)
if (Label[i] == Label[v2])
Label[i] = Label[v1];
}
else{
for (int i=0; i<nVer; i++)
if (Label[i] == Label[v1])
Label[i] = Label[v2];
}*/
- 4. void KruskalAlgo::InitAlg(){
Label.resize(nVer);
for (int i=0; i<Label.size(); i++){
Label[i]=i;
}
sort(Edges.begin(), Edges.end());
}
int KruskalAlgo::RunAlg(){ // Thuaät toaùn chính
InitAlg(); // Böôùc 1
int nE = Edges.size(), nT = 0;
for (int i=0; i<nE; i++) { // Böôùc 2
Edge e=Edges[i];
int v1=e.getV1(), v2=e.getV2();
if (Label[v1] != Label[v2]){
T.push_back(e);
UpdateLabels(v1, v2);
}
if ( (nT=T.size()) == nVer-1)
break;
}
return nT==nVer-1;
}
void KruskalAlgo::ShowT(ostream& outDev)
{
int nT = T.size(); float w=0;
for (int i=0; i<nT; i++){
outDev << T[i] << endl;
w += T[i].getW();
}
outDev << "Total weight = " << w << endl;
}
// end of File Kruskal.cpp---------------------------
- 5. // File MainPrg.cpp---------------------------------------
#include "Kruskal.h"
#include <conio.h>
void main() // Lấy dữ liệu từ file
{
KruskalAlgo g;
if (g.LoadEdges("gData.txt")){
g.RunAlg();
g.ShowT(cout);
}
else
cout << "File not found!" << endl;
getch();
}
/*
void main() // Lấy dữ liệu từ thiết bị nhập chuẩn (bàn phím console hay tập tin)
{
KruskalAlgo g;
g.LoadEdges(cin);
g.RunAlg();
g.ShowT(cout);
getch();
}
*/
// end of File MainPrg.cpp-------------------------------------------