Reputation: 37
How can I reverse not transpose an oriented graph ?
Graphe *Graphe::grapheInverse( void ){
Graphe *r = new Graphe (_adjacences.size() );
for (unsigned i = 0; i < _adjacences.size(); i++){
for (unsigned j = 0; j < _adjacences[i]->size(); j++){
//r->addArcs(j,i); this doesn't work
}
}
return r;
}
where _adjacences is : vector< vector< int > * > _adjacences;
and addArcs
is:
void Graphe::addArcs( int a_sommet1, int a_sommet2 ){
assert( 0 <= a_sommet1 && a_sommet1 < _adjacences.size() );
assert( nullptr != _adjacences[a_sommet1] );
_adjacences[a_sommet1]->push_back( a_sommet2 );
}
Example:
Graphe g( 5 );
g.addArcs( 0, 1 );
g.addArcs( 0, 4 );
g.addArcs( 1, 0 );
g.addArcs( 1, 4 );
g.addArcs( 2, 0 );
g.addArcs( 2, 1 );
g.addArcs( 2, 3 );
g.addArcs( 2, 4 );
g.addArcs( 4, 3 );
g.addArcs( 4, 1 );
// inversion du graphe :
Graphe *r = g.grapheInverse();
My full code is as follows:
Graphe.hpp
#include <iostream>
#include <vector>
using namespace std;
class Graphe
{
private:
vector< vector< int > * > _adjacences;
public:
Graphe( void );
Graphe( int a_nbSommet );
virtual ~Graphe( void );
int nbSommet( void ) const;
vector< int > * adjacences( int a_sommet );
void addArcs( int a_sommet1, int a_sommet2 );
Graphe * grapheInverse( void );
friend ostream & operator <<( ostream &, Graphe const & );
};
Graphe.cpp
#include "Graphe.hpp"
#include <algorithm>
#include <cassert>
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;
Graphe::Graphe( void )
{
}
Graphe::Graphe( int a_nbSommet ): _adjacences( a_nbSommet ){
int i;
for( i = 0; i < a_nbSommet; ++ i ){
_adjacences[i] = new vector< int >();
}
}
Graphe::~Graphe( void )
{
}
void Graphe::addArcs( int a_sommet1, int a_sommet2 ){
assert( 0 <= a_sommet1 && a_sommet1 < _adjacences.size() );
assert( nullptr != _adjacences[a_sommet1] );
_adjacences[a_sommet1]->push_back( a_sommet2 );
}
int Graphe::nbSommet( void ) const{
return _adjacences.size();
}
vector< int > *Graphe::adjacences( int a_sommet ){
assert( 0 <= a_sommet && a_sommet < _adjacences.size() );
return _adjacences[ a_sommet ];
}
Graphe *Graphe::grapheInverse( void ){
Graphe *r = new Graphe (_adjacences.size() );
for (unsigned i = 0; i < _adjacences.size(); i++)
for ( unsigned j = 0; j < _adjacences[i]->size(); j++ )
r->addArcs ((*_adjacences[i])[j],i);
return r;
}
ostream &operator <<( ostream & a_out, Graphe const & a_graphe ){
int i = 0;
int j = 0;
for( i = 0; i < a_graphe._adjacences.size(); ++ i ){
a_out << i << " : ";
for( j = 0; j < a_graphe._adjacences[i]->size(); ++ j ){
if( 0 != j ){
a_out << ", ";
}
a_out << ( a_graphe._adjacences[i]->at(j) );
}
a_out << endl;
}
return a_out;
}
my main
#include "Graphe.hpp"
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
int main( int argn, char * argv[] ){
// construction of the graph :
Graphe g( 5 );
g.addArcs( 0, 1 );
g.addArcs( 0, 4 );
g.addArcs( 1, 0 );
g.addArcs( 1, 4 );
g.addArcs( 2, 0 );
g.addArcs( 2, 1 );
g.addArcs( 2, 3 );
g.addArcs( 2, 4 );
g.addArcs( 4, 3 );
g.addArcs( 4, 1 );
// inversion of the graph :
Graphe *r = g.grapheInverse();
// printing the both lists for verification
cout << g << endl;
cout << *r << endl;
}
this gives me:
g:
0 : 1, 4
1 : 0, 4
2 : 0, 1, 3, 4
3 :
4 : 3, 1
r:
0 : 1, 2
1 : 0, 2, 4
2 :
3 : 2, 4
4 : 0, 1, 2
Upvotes: 1
Views: 319
Reputation: 32727
When making the reverse list, you don't want to use the index in the original list as the source vertex, you need to derefence the list. So you'll want to use
r->addArcs((*_adjacences[i])[j],i);
There are better ways to write that function (like range-based for loops).
Upvotes: 2