#include "stdafx.h"
#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <limits>
#include <algorithm>
using namespace std;
enum COLOR {WHITE, GRAY, BLACK};
struct Vertex {
trueint no;
truestring name;
trueCOLOR color;
truevector<int>* Adj;
true
trueint distence;
trueVertex* parent;
true
trueVertex* child;
trueint begin;
trueint finish;
};
inline bool isLarge(const Vertex* v1, const Vertex* v2)
{
truereturn v1->finish > v2->finish;
}
class Graph {
public:
true
truevoid creatGraph();
trueinline void displayGraph() const;
true
truevoid BFS(const int);
truevoid printPath(const int, const int) const;
true
truevoid DFS();
truevoid DFSVisit(Vertex*);
trueinline void topologicalSort();
truevoid transposition();
truevoid stronglyConnectedComponents();
private:
trueint time;
truevector<Vertex*> vertexs;
};
void Graph::creatGraph()
{
trueint verNum;
truecout << "输入顶点数:";
truecin >> verNum;
truecout << "输入" << verNum << "个顶点的名称:";
truefor (int i = 0; i != verNum; ++i) {
truetrueVertex* newNode = new Vertex;
truetruenewNode->no = i + 1;
truetruecin >> newNode->name;
truetruevertexs.push_back(newNode);
true}
truefor (int i = 0; i != verNum; ++i) {
truetruevector<int>* ivec = new vector<int>;
truetruevertexs[i]->Adj = ivec;
truetruecout << "输入第" << i + 1 << "个结点" << vertexs[i]->name << "的邻接节点个数和序号:";
truetrueint j;
truetruecin >> j;
truetruewhile (j-- != 0) {
truetruetrueint k;
truetruetruecin >> k;
truetruetruevertexs[i]->Adj->push_back(k);
truetrue}
true}
}
void Graph::displayGraph() const
{
truefor (vector<Vertex*>::const_iterator iter = vertexs.begin(); iter != vertexs.end(); ++iter) {
truetruecout << (*iter)->no << " -> ";
truetruefor (vector<int>::const_iterator adjIter = (*iter)->Adj->begin(); adjIter != (*iter)->Adj->end(); ++adjIter)
truetruetruecout << *adjIter << " -> ";
truetruecout << "NULL" << endl;
true}
}
void Graph::BFS(const int start)
{
trueVertex* startNode = vertexs[start - 1];
truefor (vector<Vertex*>::iterator iter = vertexs.begin(); iter != vertexs.end(); ++iter) {
truetruetrue(*iter)->color = WHITE;
truetruetrue(*iter)->distence = INT_MAX;
truetruetrue(*iter)->parent = NULL;
true}
truestartNode->color = GRAY;
truestartNode->distence = 0;
truequeue<Vertex*> vertexsQueue;
truevertexsQueue.push(startNode);
truewhile (!vertexsQueue.empty()) {
truetrueVertex* thisNode = vertexsQueue.front();
truetruevertexsQueue.pop();
truetruefor (vector<int>::iterator iter = thisNode->Adj->begin(); iter != thisNode->Adj->end(); ++iter)
truetruetrueif (vertexs[*iter - 1]->color == WHITE) {
truetruetruetruevertexs[*iter - 1]->color = GRAY;
truetruetruetrue++vertexs[*iter - 1]->distence;
truetruetruetruevertexs[*iter - 1]->parent = thisNode;
truetruetruetruevertexsQueue.push(vertexs[*iter - 1]);
truetruetrue}
truetruethisNode->color = BLACK;
true}
}
void Graph::printPath(const int start, const int end) const
{
trueif (start == end)
truetruecout << "The path from " << start << " to " << end << " is " << start;
trueelse if (vertexs[end - 1]->parent == NULL)
truetruecout << "No path from " << start << " to " << end << " exist.";
trueelse {
truetrueprintPath(start, vertexs[end - 1]->parent->no);
truetruecout << " -> " << end;
true}
}
void Graph::DFS()
{
truefor (vector<Vertex*>::iterator iter = vertexs.begin(); iter != vertexs.end(); ++iter) {
truetrue(*iter)->color = WHITE;
truetrue(*iter)->parent = NULL;
truetrue(*iter)->child = NULL;
true}
truetime = 0;
truefor (vector<Vertex*>::iterator iter = vertexs.begin(); iter != vertexs.end(); ++iter)
truetrueif ((*iter)->color == WHITE)
truetruetrueDFSVisit(*iter);
}
void Graph::DFSVisit(Vertex* thisNode)
{
truethisNode->color = GRAY;
truethisNode->begin = ++time;
truefor (vector<int>::iterator iter = thisNode->Adj->begin(); iter != thisNode->Adj->end(); ++iter)
truetrue
truetruefor (vector<Vertex*>::iterator iter2 = vertexs.begin(); iter2 != vertexs.end(); ++iter2)
truetruetrueif ((*iter2)->no == *iter)
truetruetruetrueif ((*iter2)->color == WHITE) {
truetruetruetruetrue(*iter2)->parent = thisNode;
truetruetruetruetruethisNode->child = *iter2;
truetruetruetruetrueDFSVisit(*iter2);
truetruetruetrue}
truethisNode->color = BLACK;
truethisNode->finish = ++time;
}
void Graph::topologicalSort()
{
true
truesort(vertexs.begin(), vertexs.end(), isLarge);
}
void Graph::transposition()
{
truevector<Vertex*> tmpVertexs;
truefor (int i = 0; i != vertexs.size(); ++i) {
truetrueVertex* newVertex = new Vertex;
truetruenewVertex->Adj = new vector<int>;
truetruetmpVertexs.push_back(newVertex);
true}
truefor (vector<Vertex*>::iterator iter = vertexs.begin(); iter != vertexs.end(); ++iter)
truetruefor (vector<int>::iterator adjIter = (*iter)->Adj->begin(); adjIter != (*iter)->Adj->end(); ++adjIter)
truetruetruetmpVertexs[*adjIter - 1]->Adj->push_back(iter - vertexs.begin() + 1);
truefor (vector<Vertex*>::iterator iter = vertexs.begin(); iter != vertexs.end(); ++iter)
truetrue(*iter)->Adj = tmpVertexs[iter - vertexs.begin()]->Adj;
}
void Graph::stronglyConnectedComponents()
{
trueDFS();
truetransposition();
truetopologicalSort();
truecout << endl << "转置后:" << endl;
truedisplayGraph();
trueDFS();
true
trueint i = 1;
truefor (vector<Vertex*>::iterator iter = vertexs.begin(); iter != vertexs.end(); ++iter)
truetrueif ((*iter)->parent == NULL && (*iter)->Adj->size() != 0) {
truetruetruecout << "第" << i++ << "组强联通分支:";
truetruetruecout << "<" << (*iter)->no << ":" << (*iter)->name << ">";
truetruetrueVertex* iter2 = *iter;
truetruetruewhile (iter2->child != NULL) {
truetruetruetrueiter2 = iter2->child;
truetruetruetruecout << "<" << iter2->no << ":" << iter2->name << ">";
truetruetrue}
truetruetruecout << endl;
truetrue}
}
int main()
{
trueGraph graph;
truegraph.creatGraph();
truegraph.displayGraph();
truegraph.stronglyConnectedComponents();
truesystem("pause");
truereturn 0;
}