#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
/*
// Структура описывающая ребро графа
*/
struct Edge
{
int v, w; // вершины
Edge( int v = -1, int w = -1 ) : v(v), w(w) { }
};
/*
// Представление графа как матрицы смежностей
*/
class DenseGraph
{
int Vcnt, Ecnt; // количество вершин и количество ребер
bool digraph; // является ли орграфом
vector< vector<bool> > adj; // собственно матрица
public:
DenseGraph( int V, bool digraph = false ) :
adj(V), Vcnt(V), Ecnt(0), digraph(digraph)
{
for ( int i = 0; i < V; i++ )
adj[i].assign(V, false);
}
DenseGraph( char * file, bool digraph = false );
int V() const { return Vcnt; }
int E() const { return Ecnt; }
bool directed() const { return digraph; }
void insert( Edge e )
{
int v = e.v, w = e.w;
if ( adj[v][w] == false ) Ecnt++;
adj[v][w] = true;
if ( !digraph ) adj[w][v] = true;
}
void remove( Edge e )
{
int v = e.v, w = e.w;
if ( adj[v][w] == true ) Ecnt--;
adj[v][w] = false;
if ( !digraph ) adj[w][v] = false;
}
bool edge( int v, int w )
{
return adj[v][w];
}
};
void deletespaces( string & str )
{
int index;
while ( (index = str.find(" ")) != string::npos )
str.erase(index, 1);
}
DenseGraph::DenseGraph( char * file, bool digraph )
{
string s, sum;
int vCnt = 0;
// Получаем количество вершин в графе, а за одно
// аккумулируем строки матрицы в одну строку
ifstream in( file );
if ( !in ) return;
while ( !in.eof() ) {
std::getline(in, s);
deletespaces(s);
sum += s;
vCnt++;
}
in.close();
// инициализируем параметры графа
Vcnt = vCnt;
Ecnt = 0;
this->digraph = digraph;
adj.assign(vCnt, vector<bool>(vCnt, false));
// Заполняем граф по матрице смежностей
int idx = 0;
for ( int i = 0; i < vCnt; i++ )
for( int j = 0; j < vCnt; j++ ) {
if ( sum[idx] == '1' )
insert( Edge(i, j) );
idx++;
}
}
/*
// Возвращает все ребра графа в виде вектора
*/
template <class Graph>
vector< Edge > edges( Graph & G )
{
int E = 0;
vector< Edge > a( G.E() );
for ( int v = 0; v < G.V(); v++ )
{
typename Graph::adjIterator A(G, v);
for ( int w = A.begin(); !A.end(); w = A.next() )
if ( G.directed() || v < w )
a[E++] = Edge(v, w);
}
return a;
}
template <class Graph>
vector< Edge > edges( Graph & G, int v )
{
vector< Edge > egs;
for ( int i = 0; i < G.V(); i++ )
if ( G.edge(v, i) ) egs.push_back( Edge(v, i) );
return egs;
}
/*
// Находит все циклы орграфа
*/
template <class Graph> class CYCLES
{
Graph & G;
vector< int > cycle; // текущий цикл
vector< vector<int> > cls; // все найденые циклы
bool used( int v )
{
vector< int >::iterator p = cycle.begin() + 1;
for ( ; p != cycle.end(); p++ )
if ( *p == v ) return true;
return false;
}
void go( int curV, int endV = -1 )
{
cycle.push_back(curV);
if ( curV == endV ) {
cls.push_back(cycle);
} else {
vector< Edge > egs = edges(G, curV);
vector< Edge >::iterator p = egs.begin();
for ( ; p != egs.end(); p++ )
if ( endV == -1 )
go(p->w, curV);
else if ( p->w != p->v && !used(p->w) )
go(p->w, endV);
}
cycle.pop_back();
}
public:
CYCLES( Graph & G ) : G(G)
{ for ( int i = 0; i < G.V(); i++ ) go(i); }
void printCycles()
{
vector< vector<int> >::iterator p = cls.begin();
for ( ; p != cls.end(); p++ ) {
vector< int >::iterator cl = p->begin();
for ( ; cl != p->end(); cl++ )
cout << *cl << "->";
cout << endl;
}
}
};
int main()
{
DenseGraph m_Graph( "in.txt", true );
CYCLES<DenseGraph> sc(m_Graph);
sc.printCycles();
system("PAUSE");
return 0;
}
Поиск всех циклов ориентированного графа