kruskal.h
kruskal.cpp
#pragma once
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <set>
template<class Vertex_Type, class Edge_Type>
class Kruskal
{
typedef Kruskal<Vertex_Type,Edge_Type> Self_Type ;
protected:
struct Edge_t
{
typedef typename Self_Type::Edge_t Self_Type ;
Vertex_Type v1, v2 ;
Edge_Type e ;
Edge_t(){}
Edge_t(Vertex_Type & _v1,Vertex_Type & _v2,Edge_Type & _e) :
v1(_v1),v2(_v2),e(_e)
{}
Edge_t(const Edge_t & edge):v1(edge.v1),v2(edge.v2),e(edge.e)
{}
Edge_t & operator=(const Edge_t & edge){ v1=edge.v1,v2=edge.v2,e=edge.e ;return *this ; }
bool operator<(const Self_Type & other )const { return e<other.e ; }
//friend istream & operator>>(istream & in, Self_Type & edge)
//{ in>>edge.v1>>edge.v2>>edge.e ; return in ; }
};
//
struct Vertex_t
{
Vertex_Type v ;
Vertex_t * root ;
Vertex_t(){}
Vertex_t(Vertex_Type & _v, Vertex_t * _r=0): v(_v),root(_r){}
bool operator<(const Vertex_t & other ) const { return v<other.v ; }
bool isRoot(void) const { return 0==root || root==this; }
bool isSingle(void) const { return 0==root ; }
};
//
std::vector<Edge_t> Edges ;
std::vector<Edge_t> resultEdges ;
size_t edgeNum ;
size_t vertexNum ;
std::set<Vertex_t> VexSet ;
public:
Kruskal():edgeNum(0),vertexNum(0){}
Kruskal(size_t vNum, size_t eNum): Edges(eNum),edgeNum(eNum),vertexNum(vNum){}
Kruskal(size_t vNum, size_t eNum, Edge_t & default):Edges(eNum,default),edgeNum(eNum),vertexNum(vNum){}
virtual ~Kruskal() {}
void setNum( size_t vNum, size_t eNum) { edgeNum=eNum,vertexNum=vNum ; }
virtual void sort(void)
{
std::sort(Edges.begin(),Edges.end()) ;
}
virtual void input(std::istream & in)
{
if(Edges.size()<edgeNum)
Edges.resize(edgeNum) ;
for(size_t i=0; i<edgeNum; ++i)
{
in>>Edges[i].v1>>Edges[i].v2>>Edges[i].e; // you may change this
VexSet.insert(Edges[i].v1) ;
VexSet.insert(Edges[i].v2);
}
}
friend std::istream & operator>>(std::istream & in, Self_Type & object) { object.input(in) ; return in ; }
friend std::ostream & operator<<(std::ostream & out, Self_Type & object)
{
out<<"vertex_1 vertex_2 edge " ;
std::vector<Edge_t> & edges=object.resultEdges ;
for(size_t i =0; i<edges.size() ; ++i)
out<<edges[i].v1<<" "<<edges[i].v2<<" "<<edges[i].e<<std::endl ;
return out ;
}
Vertex_t & findRoot(Vertex_t & v )
{
if (v.isRoot())
return v ;
return findRoot(*v.root) ;
}
virtual bool isInSameSet(Vertex_Type & _v1, Vertex_Type & _v2)
{
Vertex_t & v1=findRoot(*VexSet.find(_v1)) ;
Vertex_t & v2=findRoot(*VexSet.find(_v2)) ;
if(v1.v==v2.v)
return true ;
if(v1.isSingle())
v1.root=&v2 ;
else
v2.root=&v1 ;
return false;
}
void run(void)
{
sort() ;
for(size_t i=0; i<edgeNum; ++i)
{
Vertex_Type & v1=Edges[i].v1 ;
Vertex_Type & v2=Edges[i].v2 ;
if( ! isInSameSet(v1,v2) )
resultEdges.push_back( Edges[i] );
}
}
};
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <set>
template<class Vertex_Type, class Edge_Type>
class Kruskal
{
typedef Kruskal<Vertex_Type,Edge_Type> Self_Type ;
protected:
struct Edge_t
{
typedef typename Self_Type::Edge_t Self_Type ;
Vertex_Type v1, v2 ;
Edge_Type e ;
Edge_t(){}
Edge_t(Vertex_Type & _v1,Vertex_Type & _v2,Edge_Type & _e) :
v1(_v1),v2(_v2),e(_e)
{}
Edge_t(const Edge_t & edge):v1(edge.v1),v2(edge.v2),e(edge.e)
{}
Edge_t & operator=(const Edge_t & edge){ v1=edge.v1,v2=edge.v2,e=edge.e ;return *this ; }
bool operator<(const Self_Type & other )const { return e<other.e ; }
//friend istream & operator>>(istream & in, Self_Type & edge)
//{ in>>edge.v1>>edge.v2>>edge.e ; return in ; }
};
//
struct Vertex_t
{
Vertex_Type v ;
Vertex_t * root ;
Vertex_t(){}
Vertex_t(Vertex_Type & _v, Vertex_t * _r=0): v(_v),root(_r){}
bool operator<(const Vertex_t & other ) const { return v<other.v ; }
bool isRoot(void) const { return 0==root || root==this; }
bool isSingle(void) const { return 0==root ; }
};
//
std::vector<Edge_t> Edges ;
std::vector<Edge_t> resultEdges ;
size_t edgeNum ;
size_t vertexNum ;
std::set<Vertex_t> VexSet ;
public:
Kruskal():edgeNum(0),vertexNum(0){}
Kruskal(size_t vNum, size_t eNum): Edges(eNum),edgeNum(eNum),vertexNum(vNum){}
Kruskal(size_t vNum, size_t eNum, Edge_t & default):Edges(eNum,default),edgeNum(eNum),vertexNum(vNum){}
virtual ~Kruskal() {}
void setNum( size_t vNum, size_t eNum) { edgeNum=eNum,vertexNum=vNum ; }
virtual void sort(void)
{
std::sort(Edges.begin(),Edges.end()) ;
}
virtual void input(std::istream & in)
{
if(Edges.size()<edgeNum)
Edges.resize(edgeNum) ;
for(size_t i=0; i<edgeNum; ++i)
{
in>>Edges[i].v1>>Edges[i].v2>>Edges[i].e; // you may change this
VexSet.insert(Edges[i].v1) ;
VexSet.insert(Edges[i].v2);
}
}
friend std::istream & operator>>(std::istream & in, Self_Type & object) { object.input(in) ; return in ; }
friend std::ostream & operator<<(std::ostream & out, Self_Type & object)
{
out<<"vertex_1 vertex_2 edge " ;
std::vector<Edge_t> & edges=object.resultEdges ;
for(size_t i =0; i<edges.size() ; ++i)
out<<edges[i].v1<<" "<<edges[i].v2<<" "<<edges[i].e<<std::endl ;
return out ;
}
Vertex_t & findRoot(Vertex_t & v )
{
if (v.isRoot())
return v ;
return findRoot(*v.root) ;
}
virtual bool isInSameSet(Vertex_Type & _v1, Vertex_Type & _v2)
{
Vertex_t & v1=findRoot(*VexSet.find(_v1)) ;
Vertex_t & v2=findRoot(*VexSet.find(_v2)) ;
if(v1.v==v2.v)
return true ;
if(v1.isSingle())
v1.root=&v2 ;
else
v2.root=&v1 ;
return false;
}
void run(void)
{
sort() ;
for(size_t i=0; i<edgeNum; ++i)
{
Vertex_Type & v1=Edges[i].v1 ;
Vertex_Type & v2=Edges[i].v2 ;
if( ! isInSameSet(v1,v2) )
resultEdges.push_back( Edges[i] );
}
}
};
#include "kruskal.h"
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <set>
#include <string>
using namespace std ;
struct edg_t
{
int vec1,vec2, weight ;
friend istream & operator>>(istream & in, edg_t & edg)
{
in>>edg.vec1>>edg.vec2>>edg.weight ;
return in ;
}
};
bool cmp(const edg_t & left, const edg_t & right )
{
return left.weight<right.weight ;
}
void kruskal(fstream & fin) ;
size_t findRoot(vector<int> & vec, int index) ;
template<class vetex_type, class edge_type>
void test(istream & fin)
{
int vecNum, edgNum ;
fin>>vecNum>>edgNum ;
{
Kruskal<vetex_type,edge_type> sun(vecNum, edgNum) ;
fin>>sun ;
sun.run() ;
cout<<sun ;
}
getchar() ;
}
int _tmain(int argc, _TCHAR* argv[])
{
fstream fin("data.txt",ios::in) ;
test<string,int>(fin) ;
test<char,int>(fin) ;
test<int,int>(fin) ;
cout<<" --------------- " ;
kruskal(fin) ;
getchar() ;
fin.close() ;
return 0;
}
// find the root of the set with the vec[index] in it
size_t findRoot(vector<int> & vec, int index)
{
if(index>=vec.size())
return 0 ;
if( vec[index]==-1) // is it a root ?
return index ;
return findRoot(vec,vec[index]) ;
}
//
void kruskal(fstream & fin)
{
if(!fin)
cout<<"Error in open file! ";
//cout<<fin.rdbuf() ;
int VecNum, EdgNum ;
fin>>VecNum>>EdgNum ;
vector<edg_t> edgVec(EdgNum) ;
vector<int> resultVec(VecNum,-1) ;
for(int i=0; i<EdgNum; i++)
fin>>edgVec[i] ;
//step 1 : sort by edge
sort(edgVec.begin(), edgVec.end(), ptr_fun(cmp));
// step 2: for each edge in the sorted @edgVec,
// select it's two vertex if they are not in the same set and union the two set
for(int i=0; i<EdgNum; i++)
{
edg_t & edg=edgVec[i] ;
// find the two set of each vertex of the edge
size_t lRoot=findRoot(resultVec,edg.vec1-1);
size_t rRoot=findRoot(resultVec,edg.vec2-1);
if(lRoot==rRoot) // are they in the same set ?
continue ;
// here we union the two set
if(-1==resultVec[lRoot])
resultVec[lRoot]=rRoot ;
else
resultVec[rRoot]=lRoot ;
cout<<edg.vec1<<" "<<edg.vec2<<" "<<edg.weight
<<endl ; // print the result
}
}
data.txt
9 14
sda erb 4
sda gggh 8
erb itc 8
erb gggh 11
itc qwed 7
itc xcvf 4
itc asdfi 2
qwed erte 9
qwed xcvf 14
erte xcvf 10
xcvf dfgg 2
dfgg gggh 1
dfgg asdfi 6
gggh asdfi 7
9 14
a b 4
a h 8
b c 8
b h 11
c d 7
c f 4
c i 2
d e 9
d f 14
e f 10
f g 2
g h 1
g i 6
h i 7
9 14
1 2 4
1 8 8
2 3 8
2 8 11
3 4 7
3 6 4
3 9 2
4 5 9
4 6 14
5 6 10
6 7 2
7 8 1
7 9 6
8 9 7
9 14
1 2 4
1 8 8
2 3 8
2 8 11
3 4 7
3 6 4
3 9 2
4 5 9
4 6 14
5 6 10
6 7 2
7 8 1
7 9 6
8 9 7