update Graph class, not tested yet.
This commit is contained in:
@@ -13,11 +13,11 @@ template <typename Tv, typename Te>
|
||||
class Graph{
|
||||
private:
|
||||
void reset(); //reset all information of all vertices and edges
|
||||
void BFS(int, int&);
|
||||
void DFS(int, int&);
|
||||
void BCC(int, int&, Stack<int>&);
|
||||
bool TSort(int, int&, Stack<Tv>*);
|
||||
template <typename PU> void PFS(int, PU);
|
||||
void BFS(int, int&); //Breadth First Search
|
||||
void DFS(int, int&); //Depth First Search
|
||||
void BCC(int, int&, Stack<int>&); //Biconnected Component
|
||||
bool TSort(int, int&, Stack<Tv>*); //Topological Sort
|
||||
template <typename PU> void PFS(int, PU); //Priority First Search
|
||||
|
||||
public:
|
||||
int num_of_vertices;
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
void prim(int);
|
||||
void dijkstra(int);
|
||||
Stack<Tv>* tSort(int);
|
||||
template <typename PU> void pfd(int, PU);
|
||||
template <typename PU> void pfs(int, PU);
|
||||
};
|
||||
|
||||
//private methods
|
||||
@@ -60,7 +60,7 @@ template <typename Tv, typename Te>
|
||||
void Graph<Tv, Te>::reset(){//reset all information of all vertices and edges
|
||||
for(int ix = 0; ix != num_of_vertices; ++ix){
|
||||
status(ix) = UNDISCOVERED;
|
||||
priority(ix) = 0;
|
||||
priority(ix) = INT_MAX;
|
||||
dtime(ix) = -1;
|
||||
ftime(ix) = -1;
|
||||
parent(ix) = -1;
|
||||
@@ -118,6 +118,85 @@ void Graph<Tv, Te>::DFS(int x, int& clock){
|
||||
status(x) = VISITED;
|
||||
}
|
||||
|
||||
#define hca(x) ftime(x)
|
||||
template <typename Tv, typename Te>
|
||||
void Graph<Tv, Te>::BCC(int x, int &clock, Stack<int> &S) {
|
||||
status(x) = DISCOVERED;
|
||||
S.push(x);
|
||||
hca(x) = dtime(x) = ++clock;
|
||||
for (int v = firstNeighbor(x); v != -1; v = nextNeighbor(x, v)) {
|
||||
switch (status(v)) {
|
||||
case UNDISCOVERED:
|
||||
type(x, v) = TREE;
|
||||
BCC(v, clock, S);
|
||||
if (hca(v) < dtime(x)) hca(x) = MIN(hca(v), hca(x));
|
||||
else {//a biconnected component found
|
||||
while (S.pop() != x);
|
||||
S.push(x);
|
||||
}
|
||||
break;
|
||||
|
||||
case DISCOVERED:
|
||||
type(x, v) = BACKWARD;
|
||||
if (parent(x) != v) hca(x) = MIN(hca(x), dtime(v));
|
||||
break;
|
||||
|
||||
case VISITED:
|
||||
default:
|
||||
type(x, v) = dtime(x) < dtime(v) ? FORWARD : CROSS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef hca
|
||||
|
||||
template <typename Tv, typename Te>
|
||||
bool Graph<Tv, Te>::TSort(int x, int &clock, Stack<Tv> *S){
|
||||
status(x) = DISCOVERED;
|
||||
dtime(x) = ++clock;
|
||||
for(int v = firstNeighbor(x); v != -1; v = nextNeighbor(x, v)){
|
||||
switch(status(v)){
|
||||
case UNDISCOVERED:
|
||||
status(v) = DISCOVERED;
|
||||
type(x, v) = TREE;
|
||||
if (!TSort(v, clock, S)) return false;
|
||||
break;
|
||||
|
||||
case DISCOVERED:
|
||||
type(x, v) = BACKWARD;
|
||||
return false;
|
||||
|
||||
case VISITED:
|
||||
default:
|
||||
type(x, v) = dtime(x) > dtime(v)? FORWARD: CROSS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
S->push(x);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Tv, typename Te>
|
||||
template <typename PU>
|
||||
void Graph<Tv, Te>::PFS(int x, PU PrioUpdater){
|
||||
priority(x) = 0;
|
||||
status(x) = VISITED;
|
||||
parent(x) = -1;
|
||||
while(1){
|
||||
for (int v = firstNeighbor(x); v != -1; v = nextNeighbor(x, v))
|
||||
PrioUpdater(this, x, v);
|
||||
//find current highest priority
|
||||
for (int shortest = INT_MAX, v = 0; v != num_of_vertices; ++v)
|
||||
if (status(v) == UNDISCOVERED && priority(v) < shortest) {
|
||||
shortest = priority(v);
|
||||
x = v;
|
||||
}
|
||||
if (status(x) == VISITED) break;
|
||||
status(x) == VISITED;
|
||||
type(parent(x), x) = TREE;
|
||||
}
|
||||
}
|
||||
|
||||
//Graph related algorithms
|
||||
|
||||
template <typename Tv, typename Te>
|
||||
@@ -142,4 +221,83 @@ void Graph<Tv, Te>::dfs(int start){
|
||||
} while ((x = ++x % num_of_vertices) != start);
|
||||
}
|
||||
|
||||
#endif
|
||||
template <typename Tv, typename Te>
|
||||
void Graph<Tv, Te>::bcc(int start){
|
||||
reset();
|
||||
int clock = 0;
|
||||
int curr = start;
|
||||
Stack<int> S;
|
||||
do{
|
||||
if (status(curr) == UNDISCOVERED) {
|
||||
BCC(curr, clock, S);
|
||||
S.pop(); //remove the last element in the Stack, which is the start point of current connected components
|
||||
}
|
||||
} while ((curr = ++curr % num_of_vertices) £¡ = start);
|
||||
}
|
||||
|
||||
//Prim Algorithm
|
||||
template <typename Tv, typename Te>
|
||||
class PrimPU{
|
||||
public:
|
||||
void operator()(Graph<Tv, Te> *G, int parent, int v){
|
||||
if(G->status(v) == UNDISCOVERED){
|
||||
if (G->weight(parent, v) < G->priority(v)) {
|
||||
G->priority = G->weight(parent, v);
|
||||
G->parent(v) = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tv, typename Te>
|
||||
void Graph<Tv, Te>::prim(int x){
|
||||
pfs(x, PrimPU<Tv, Te>());
|
||||
}
|
||||
|
||||
//Dijkstra Algorithm
|
||||
|
||||
template <typename Tv, typename Te>
|
||||
class DijkstraPU{
|
||||
public:
|
||||
void operator()(Graph<Tv, Te> *G, int parent, int v){
|
||||
if(G->status(v) == UNDISCOVERED){
|
||||
if(G->priority(parent) + G->weight(parent, v) < G->priority(v)){
|
||||
G->priority(v) = G->priority(parent) + G->weight(parent, v);
|
||||
G->parent(v) = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tv, typename Te>
|
||||
void Graph<Tv, Te>::dijkstra(int x){
|
||||
pfs(x, DijkstraPU<Tv, Te>());
|
||||
}
|
||||
|
||||
template <typename Tv, typename Te>
|
||||
Stack<Tv>* Graph<Tv, Te>::tSort(int start){
|
||||
reset();
|
||||
Stack<Tv> *S;
|
||||
int clock = 0;
|
||||
int curr = start;
|
||||
do{
|
||||
if(status(curr) == UNDISCOVERED && !TSort(curr, clock, S)){
|
||||
while (!S->empty()) S->pop();
|
||||
break;
|
||||
}
|
||||
} while ((curr = ++curr % num_of_vertices) != start);
|
||||
return S;
|
||||
}
|
||||
|
||||
template <typename Tv, typename Te>
|
||||
template <typename PU>
|
||||
void Graph<Tv, Te>::pfs(int start, PU PrioUpdater){
|
||||
reset();
|
||||
int curr = start;
|
||||
do{
|
||||
if (status(curr) == UNDISCOVERED)
|
||||
PFS(curr, PrioUpdater);
|
||||
} while ((curr = ++curr % num_of_vertices) != start);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
2
thu_dsa/chp6/Graph.md
Normal file
2
thu_dsa/chp6/Graph.md
Normal file
@@ -0,0 +1,2 @@
|
||||
Conclusion on Chapter Six: Graph
|
||||
================================
|
||||
@@ -11,7 +11,7 @@ public:
|
||||
int parent = -1;
|
||||
int dTime = -1;
|
||||
int fTime = -1;
|
||||
int priority = 0;
|
||||
int priority = INT_MAX;
|
||||
int inDegree = 0;
|
||||
int outDegree = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user