bfsTree empty with unused value warning - c++

I am trying to implement bfsTree. It should take a graph as input and give the bfs tree as output. However the line that adds the edge to the bfs tree seems to be not working. The bfstree is empty. I think it is related to this unused value warning. Why it gives the warning? And how to fix it? Thanks.
Here is the warning:
vertex.cpp:35:10: warning: expression result unused [-Wunused-value]
for (neighbor; neighbor != this->_neighbors.end(); neighbor++) {
Here is the bfs tree code snippet:
Graph Bicc::breadthFirstSearch(Graph& sparseGraph) {
Graph bfsTree;
auto lev = 0;
vector<Vertex> verticies = sparseGraph.getVerticies();
for(int i = 0; i < verticies.size(); i++){
verticies[i].color = "white";
verticies[i].level = lev;
}
Vertex start = verticies[0];
list<Vertex> VertexQueue;
VertexQueue.push_back(start);
while (!VertexQueue.empty())
{
Vertex current = VertexQueue.front();
current.color = "gray"; //current vertex is being processed
auto neighbors = current.getNeighbors();
//process all neighbors of current vertex
for(auto n = neighbors.begin(); n != neighbors.end(); n++) {
if (n->color == "white") { // This is an unvisited vertex
n->level = lev + 1; // Set level
n->parent = &current; // Set parent
n->color = "gray"; // Set color visited
bfsTree.add(current, *n); //add the edge to bfsTree
VertexQueue.push_back(*n); // Add it to the queue
}
}
VertexQueue.pop_front(); // Pop out the processed vertex
++lev; // The next level
}
return bfsTree;
}
Here is the vertex.cpp code snippet that was called by the warning:
bool Vertex::hasNeighbor(const Vertex& vertex) const {
auto neighbor = this->_neighbors.begin();
for (neighbor; neighbor != this->_neighbors.end(); neighbor++) {
if (*neighbor == vertex) {
break;
}
}
return neighbor != this->_neighbors.end();
}

Related

My Dijkstra algorithm's not choosing the shortes path

i tried to code Dijkstra algorithm with two custom structs of vertexes and their edges for my custom graph, the algorithm compiles but it makes wrong choice choosing the best distance. the code is as following.
class Graph {
struct Edge;
struct Vertex {
std::string _data; //name of vertex
std::list<Edge*> _ins;
std::list<Edge*> _outs;
bool visited;
int BestDist;//best distance from source to sink
};
struct Edge {
int _weight;
Vertex *_from;
Vertex *_to;
bool travelled; //if the edge has been travalled
};
//Graph of String as key to Values as vertexes
std::unordered_map<std::string, Vertex *> _mainData;
//Dijkstra Algo
int BestDistance(std::string source, std::string sink) {
//to save vertexes names
std::queue<std::string> q;
//for each vertex set dist and path to infinity
for (auto startItr : _mainData)
{
startItr.second->BestDist = Max;
startItr.second->visited = false;
for (auto kachal : startItr.second->_outs)
{
kachal->travelled = false;
}
}
//set source distacne to 0 sicen it is visiting itself
_mainData[source]->BestDist = 0;
q.push(source);
//while there is unknown distance vertex and we havent reach sink yet
while (!q.empty() )
{
//smallest unknow distance vertex
std::string currentVer = q.front(); q.pop();
//set that vertex to visited
_mainData[currentVer]->visited = true;
//for each vertex adj to current vertex
for (auto adjVer : _mainData[currentVer]->_outs) {
//if that vertex is not visted
if (!adjVer->travelled) {
int cvw = adjVer->_weight; //cost of edge from cuurent vertex to adj vertex
//if current vert.distance +cvw < adj vertex distance
if (_mainData[currentVer]->BestDist + cvw < _mainData[adjVer->_to->_data]->BestDist) {
//update adj vertex
q.push(adjVer->_to->_data);
//deacrease adj vertex distacne to current distacne + cvw
_mainData[adjVer->_to->_data]->BestDist = _mainData[currentVer]->BestDist + cvw;
//marked the travlled edge true
adjVer->travelled = true;
}
}
}
}
return _mainData[sink]->BestDist;
}
and here is my main:
#include "stdafx.h"
#include "Graph.h"
#include <iostream>
int main()
{
Graph myGraph;
myGraph.Add("A");
myGraph.Add("B");
myGraph.Add("C");
myGraph.Add("D");
myGraph.Add("E");
myGraph.Add("F");
myGraph.Add("G");
myGraph.Connect("A", "B",20);
myGraph.Connect("A", "C",30);
myGraph.Connect("B", "D",200);
myGraph.Connect("C", "F",100);
myGraph.Connect("C", "G",200);
myGraph.Connect("D", "E",50);
myGraph.Connect("E", "F",1);
myGraph.Connect("F", "G",30);
std::cout << "best distacne example : " << myGraph.BestDistance("A", "G");
so when i run the code, the best distance from A to G shoudl be returned as 160 (A->C->F->G) but the code returns 280 which is (A->C->G). I can provide my Add and Connect functions but i'm sure they are working correctly.
so after analyzing above algorithm i realized my mistake was to mark each edge as being traveled or not and make decisions based on that. what i should have done was to mark each Vertex for being visited or not . the rest is ok. so this is the correct version of my implementation of Dijkstra Algorithm finding the shortest path in a positively weighted graph. hope it helps
//Dijkstra Algo
int BestDistance(std::string source, std::string sink) {
//to save vertexes names
std::queue<std::string> q;
//for each vertex set dist and path to infinity
for (auto startItr : _mainData)
{
startItr.second->BestDist = Max;
startItr.second->visited = false;
}
//set source distacne to 0 sicen it is visiting itself
_mainData[source]->BestDist = 0;
q.push(source);
//while there is unknown distance vertex and we havent reach sink yet
while (!q.empty() )
{
//smallest unknow distance vertex
std::string currentVer = q.front(); q.pop();
//set that vertex to visited
_mainData[currentVer]->visited = true;
//for each vertex adj to current vertex
for (auto adjVer : _mainData[currentVer]->_outs) {
//if that vertex is not visted
if (!adjVer->_to->visited) {
int cvw = adjVer->_weight; //cost of edge from cuurent
//vertex to adj vertex
//if current vert.distance +cvw < adj vertex distance
if (_mainData[currentVer]->BestDist + cvw <
_mainData[adjVer->_to->_data]->BestDist) {
q.push(adjVer->_to->_data);
//deacrease adj vertex distacne to current distacne + cvw
_mainData[adjVer->_to->_data]->BestDist = _mainData[currentVer]->BestDist + cvw;
//setting the path of adj vertext to his previous one
_mainData[adjVer->_to->_data]->path = _mainData[currentVer];
}
}
}
}
return _mainData[sink]->BestDist;
}

How to check the graph is 2-colorable or not?

I want to find whether the graph is 2-colorable or not more ie. bipartite or non-bipartite.
Here is my code in C++ I'm using Welsh Powell Algorithm but something is wrong in the code may be I am missing some corner cases or some logical mistake.
Input n=no. of vertex, m = no. of edges, 0 based indexing
#include <iostream>
#include <algorithm>
using namespace std;
pair <int,int> s[1001];
int comp( pair <int,int> s1, pair <int,int> s2)
{
if(s1.first>s2.first)
return 0;
else
return 1;
}
int main()
{
int n,i,j,k,flag=0;
bool a[1001][1001]={false};
int s1[1001]={0};
int s3[1001]={0};
for(i=0;i<1001;i++)
{
s[i].first=0;
s[i].second=i;
//s1[i]=0;
}
long long m;
cin>>n>>m;
while(m--)
{
int x,y;
cin>>x>>y;
if(x==y)
continue;
a[x][y]=true;
a[y][x]=true;
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(a[i][j]==true )
s[i].first++;
sort(s,s+n,comp);
int color=1,p=0,z,f;
for(i=0;i<n;i++)
{
k = s[n-i-1].second;
if(s1[k]==0)
{
s1[k]=color;
p=0;
s3[p++]=k;
for(j=n-1;j>=0;j--)
{
f=0;
if(s1[s[j].second]==0)
{
for(z=0;z<p;z++)
{
if(a[s3[z]][s[j].second]==false || s3[z]==s[j].second)
continue;
else
{
f=1;
break;
}
}
if(f==1)
continue;
else
{
s3[z]=s[j].second;
p++;
s1[s[j].second]=color;
}
}
}
color++;
}
if(color==3)
break;
}
for(i=0;i<n;i++)
if(s1[i]==0)
{
flag=1;
break;
}
if(flag==1)
cout<<"NO\n";
else
cout<<"YES\n";
return 0;
}
To show that a graph is bipartite, you do not need a fancy algorithm to check. You can simply use a coloring DFS (Depth-First Search) function. It can be implemented as follows:
int color[100005]; //I assume this is the largest input size, initialise all values to -1.
vector<int> AdjList[100005]; //Store the neighbours of each vertex
bool flag = true; //Bipartite or Not Bipartite
void dfs(int x, int p){ //Current vertex, Parent Vertex
if (!flag) return;
if (p == -1) color[x] = 0;
else color[x] = 1 - color[p];
for (int i = 0; i < AdjList[x].size(); ++i){ //For Every Neighbour
int v = AdjList[x][i]; //Vertex to be checked
if (color[v] == color[x]){ //Same color -> Not bipartite
flag = false;
return;
}
if (color[v] == -1){ //Unchecked
dfs(v,x); //color
}
}
}
Original Problem : https://www.codechef.com/problems/CHFNFRN
#Benson Lin Thank You For Such Help.
Well the problem with your ans is it fails if the graph is disconnected i.e if it has for then 2 disconnected subgraph.
As we are selecting source node at random the above code just check for that the subgraph with that node and gives the ans only for the subgraph not for the graph.
With small change in the above code we can solve this.
int colorArr[1001];
bool isBipartite(bool G[][1001], int src,int n)
{
colorArr[src] = 0;
queue <int> q;
q.push(src);
while (!q.empty())
{
int u = q.front();
q.pop();
// Find all non-colored adjacent vertices
for (int v = 0; v < n; ++v)
{
// An edge from u to v exists and destination v is not colored
if (G[u][v]==true && colorArr[v] == -1)
{
// Assign alternate color to this adjacent v of u
colorArr[v] = 1 - colorArr[u];
q.push(v);
}
if(G[u][v]==true && colorArr[u]==colorArr[v] && u!=v)
return false;
// An edge from u to v exists and destination v is colored with
// same color as u
}
}
// call the function with source node which is not color.
int count=0;
for(int i=0;i<n;i++)
{
if(colorArr[i]==-1)
{
if(isBipartite(G,i,n))
continue;
else
return false;
}
for(int j=0;j<n;j++)
{
if(G[i][j]==true )
{
if(colorArr[i]==colorArr[j] && colorArr[i]!=-1)
return false;
}
}
}
return true;
}
BFS can be used, by coloring the alternate levels with different colors and stopping if two nodes of the same color are found adjacent (not bipartite) or no such inconsistent coloring is found (bipartite). Here is the python code (adj being the adjacency list for the input graph to be checked):
def bipartite(adj):
color = [None]*len(adj)
for vertex in range(len(adj)):
if not color[vertex]:
queue = [vertex]
color[vertex] = 'red'
while len(queue) > 0:
u = queue.pop(0)
for v in adj[u]:
if color[v] == color[u]:
return 0
if not color[v]:
queue.append(v)
color[v] = 'red' if color[u] == 'blue' else 'blue'
return 1
The following animation shows the output of a bfs run on a given input graph and a 2-coloring of the graph (the bfs queue is also shown).

degree of connection between 2 nodes in a social graph

I'm trying to find out the degree of connection between 2 entities in a social graph where
1 hop : 1st Degree
2 hop : 2nd Degree
3 hop : 3rd Degree
And so on.
The vertices are the entities and the edges are the friendship between the two entities. Given such a graph I want to analyse the graph and answer the query as to what is the type of connection between the entities.It can be disconnected graph.In case of no connection it'll return 0.
It takes the input as-
Number_of_vertices Number_of_Edges
Edge 1
Edge 2
(So on.)
Query
Output
The degree of connection
Example
Input
5 4
Abhs Krax // Edge 1
Harry Idrina // Edge 2
Harry Jigma // Edge 3
Harry Krax // Edge 4
Abhs Jigma // Query
Output
Degree : 3
I've used BFS to find out the depth between 2 nodes, but my program works only for degree 1. It fails to test the next subsequent member of the queue thus stuck at testing only the 1st member of the queue. What did I miss in my code? The problem is in Connection() function which I couldn't trace.
#include <iostream>
#include <list>
#include <string>
using namespace std;
class Vertex // Each vertex of the graph is represented by the object of the Vertex class
{
public:
// Fields in every vertex node
string name;
std::list<Vertex*> adjacencyList;
bool status;
int depth;
// Constructor which initializes the node
Vertex(string id)
{
name = id;
adjacencyList = list<Vertex*>();
status = false;
depth =0;
}
// Function to add edges by pushing the vertices to its adjacency list
void addEdge(Vertex *v)
{
adjacencyList.push_back(v);
}
};
class Graph{
public:
// Fields of the Graph node
int N;
std::list<Vertex> vertexList;
// Functions to be implemented
int Connection(Vertex,Vertex);
Graph(int n){ // Constructor
N = n;
vertexList = list<Vertex>();
}
/* This function first checks whether the vertex has been already added
to Vertex List of the Graph. If not found it would create the vertex
node and push the node into Vertex List. Then the edges are added by
updating the adjacency list of respective vertices. */
void addEdge(string to, string from ){
if(find(to))
{
Vertex entity_1 = Vertex(to); // New vertex node creation
vertexList.push_back(entity_1); // Pushing to the Vertex List
}
if(find(from))
{
Vertex entity_2 = Vertex(from);
vertexList.push_back(entity_2);
}
Vertex *v1 = &(*(find_it(to)));
Vertex *v2 = &(*(find_it(from)));
v1->addEdge(v2); // Updating respective adjacency list
v2->addEdge(v1);
}
// Function to check whether the vertex is already added in the Vertex List
int find(string check)
{
list<Vertex>::iterator it;
it = find_it(check);
if(it==vertexList.end())
return 1;
else
return 0;
}
// Function which returns pointer to a Vertex in the Vertex List
list<Vertex>::iterator find_it(string check)
{
list<Vertex>::iterator it;
for (it = vertexList.begin(); it != vertexList.end(); it++)
if((check.compare(it->name))==0)
break;
return it;
}
};
int main()
{
int numVertices,numEdges,i,result;
string to,from,queryTo,queryFrom;
cin>>numVertices>>numEdges;
Graph G = Graph(numVertices); // Creating the Graph object
for( i=0;i<numEdges;i++)
{
cin>>to>>from;
G.addEdge(to,from); // Adding Edges to Graph
}
cin>>queryTo>>queryFrom;
// The function you have to write is called here where the address of vertex
// node is passed.
result = G.Connection((*(G.find_it(queryTo))),(*(G.find_it(queryFrom))));
if(!result)
cout<<"No Connection";
else
cout<<"Degree : "<<result;
return 0;
}
int Graph::Connection(Vertex v1,Vertex v2)
{
// Mark all the vertices as not visited
Vertex s=Vertex("xx");
int i=0;
//list<Vertex>::iterator it;
Vertex *temp=&(*(vertexList.begin()));
while(!temp)
temp->status = false,++temp;
// Create a queue for BFS
list<Vertex> queue;
// Mark the current node as visited and enqueue it
v1.status=true;
queue.push_back(v1);
// it will be used to get all adjacent vertices of a vertex
int depth;
while (!queue.empty())
{
depth=0;
// Dequeue a vertex from queue and print it
s = queue.front();
queue.pop_front();
// Get all adjacent vertices of the dequeued vertex s
// If a adjacent has not been visited, then mark it visited
// and enqueue it
temp=s.adjacencyList.front();
while(temp!=NULL)
{
++depth;
// If this adjacent node is the destination node, then return true
if ((v2.name.compare(temp->name))==0)
{
v2.depth=depth;
return v2.depth;
}
// Else, continue to do BFS
if(temp->status==false)
{
temp->status = true;
queue.push_back(*temp);
}
++temp;
}
}
return 0;
}
I'm going to assume that the degree of connection you are trying to compute is the shortest path distance between nodes (with uniform edge costs). You can use Floyd-Warshall to pre-process the graph and answer queries in O(1) time. It's really simple to implement.
int a[N][N]; /* adjacency matrix where N is max node count */
/* build graph here and init distances between distinct nodes to +INFINITY */
/* n is number of nodes */
for(int k = 0; k < n; k++)
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]);
To answer a query (x,y) you print dist[x][y].
Your BFS solution looks unnecessarily complicated. Use a vector<in> g[N] to represent your graph. Add an edge x->y with g[x].push_back(y). BFS would look like:
queue<int> Q;
Q.push(s); /* start node */
for(int i = 0; i < n; i++)
{ dist[i] = INFINITY;
}
dist[s] = 0; /* distance to s is set to 0 */
while(Q.empty() == false)
{ int x = Q.front(); Q.pop();
for(int i = 0; i < g[x].size(); i++)
{ int y = g[x][i];
/* process edge x->y */
if(dist[y] == INFINITY)
{ dist[y] = dist[x] + 1;
Q.push(y);
}
}
}
distance between s and any other node t is dist[s][t].
Your code also crashes in a segmentation fault, if you try to find a connection with degree 1. Given your graph try to find "Harry Krax".
I think the mistake is using a pointer Vertex * temp = temp=s.adjacencyList.front(); and later trying to access the next Vertex by ++temp;.
This is not how std::list in combination with pointers work.
If you want to access the next Vertex with ++temp, than you might want to use iterators std::list<x>::iterator temp.
What you are trying to do works with arrays like int a[N], because the elements of an array are adjacent in memory.
With int * aptr = a. ++aptr says that temp is to move to another location in memory that is the size of one int further away.
std::list<x> does not do this. Here the elements can be scatter at different places in memory. (Simplified) it's value and pointers to the previous and next element are stored.

heapified vector throws invalid heap on push_heap call

I am working on a simple 4 neighbour c++ implementation of A* path finding, using an stl heapified vector(with a less than predicate). When I run the program, It throws an invalid heap debug assertation. I can run through the code in the debugger, and inspected the data stored in the vector, which is correctly storing positions in ascending order of F cost. I can't quite see what I'm doing wrong:
//simple function for finding the index of a position in a vector that matches a search position
int find(std::vector<AStarPosition*>& p_Vec,AStarPosition* p_SearchParam)
{
for (size_t i = 0; i < p_Vec.size();i++)
{
if(p_Vec[i]->equals(p_SearchParam))
return i;
}
return -1;
}
//min heap predicate function
bool less(AStarPosition* a, AStarPosition* b)
{
return (a->F < b->F);
}
void AIManager::getNextPathCell(glm::vec3 p_startPosition, glm::vec3 p_targetPosition,std::vector<glm::ivec2>& path)
{
glm::ivec2 startPos = m_maze->getGridCell(p_startPosition);
glm::ivec2 goalPos = m_maze->getGridCell(p_targetPosition);
AStarPosition* start = m_Pool->getPosition(nullptr,startPos.x,startPos.y);
AStarPosition* goal = m_Pool->getPosition(nullptr,goalPos.x,goalPos.y);
start->estimateCost(goal);
bool pathFound = false;
//used to hold positions representing visited grid positions
std::vector<AStarPosition*> usedList;
//create a min heap to hold positions
std::vector<AStarPosition*> openList;
//add the start to the min heap
openList.push_back(start);
std::make_heap(openList.begin(),openList.end(),less);
//set all closed list values to zero (false)
for (size_t i = 0; i < m_closedList.size();i++)
{
std::fill(m_closedList[i].begin(),m_closedList[i].end(),0);
}
//main algorithm:
while(openList.size() > 0)
{
//remove root from openList (position with lowest F cost)
AStarPosition* parent = openList.front();
std::pop_heap(openList.begin(),openList.end(),less);
openList.pop_back();
usedList.push_back(parent);
//if current position == goal
if(parent->equals(goal))
{
pathFound = true;
break;
}
//get successor positions (4)
m_closedList[parent->x][parent->y] = 1;
AStarPosition* successors[4];
//NORTH
successors[0] = m_Pool->getPosition(parent,0,1);
//WEST
successors[1] = m_Pool->getPosition(parent,1,0);
//SOUTH
successors[2] = m_Pool->getPosition(parent,0,-1);
//EAST
successors[3] = m_Pool->getPosition(parent,-1,0);
//for each successor loop
for (int i = 0; i < 4;i++)
{
//if position is a wall or outside maze maze
if(!m_maze->isOk(glm::ivec2(successors[i]->x,successors[i]->y)))
{
//continue
successors[i]->inUse = false;
successors[i] = nullptr;
continue;
}
//if position has been visited
if(m_closedList[successors[i]->x][successors[i]->y]==1)
{
//find position within used list, as more checks are needed
int pos = find(usedList,successors[i]);
//if it has
if(pos!=-1)
{
//and the closed list is less or equal to the successor
//ie a better path than successor
if(usedList[pos]->G <= successors[i]->m_Parent->G+10)
{
//return position to pool and skip to next successor
successors[i]->inUse = false;
successors[i] = nullptr;
continue;
}
else
{
//remove position from the closed list, and return position to pool
usedList[pos]->inUse = false;
m_closedList[successors[i]->x][successors[i]->y] = 0;
usedList.erase(usedList.begin()+pos);
}
}
}
//else if current exists within openlist
int pos = find(openList,successors[i]);
if(pos!=-1)
{
//if current G cost is lower (closer to start, so better path), set openlist entry G as current G and copy parent
if(openList[pos]->G > successors[i]->G)
{
//recalculate F score of openlist entry
openList[pos]->G=successors[i]->G;
openList[pos]->m_Parent=successors[i]->m_Parent;
openList[pos]->estimateCost(goal);
//and resort list
std::sort_heap(openList.begin(),openList.end(),less);
}
successors[i]->inUse = false;
successors[i] = nullptr;
continue;
}
//else not in open list
else
{
//insert successor into open list
openList.push_back(successors[i]);
successors[i]->estimateCost(goal);
////////////////////////////////////////////////////
//line below crashes program
std::push_heap(openList.begin(),openList.end(),less);
}
}
}
if(pathFound)
{
//reconstruct path
AStarPosition* current = usedList.back();
while(!start->equals(current))
{
path.push_back(glm::ivec2(current->x,current->y));
current=current->m_Parent;
}
}
//and clean up
for (std::vector<AStarPosition*>::iterator it = openList.begin();it!=openList.end();)
{
(*it)->inUse=false;
it = openList.erase(it);
}
for (std::vector<AStarPosition*>::iterator it = usedList.begin();it!=usedList.end();)
{
(*it)->inUse=false;
it = usedList.erase(it);
}
}
I've marked the line that is causing the crash. Am I using the heap functions incorrectly?

Performance of Dijkstra's algorithm implementation

Below is an implementation of Dijkstra's algorithm I wrote from the pseudocode in the Wikipedia article. For a graph with about 40 000 nodes and 80 000 edges, it takes 3 or 4 minutes to run. Is that anything like the right order of magnitude? If not, what's wrong with my implementation?
struct DijkstraVertex {
int index;
vector<int> adj;
vector<double> weights;
double dist;
int prev;
bool opt;
DijkstraVertex(int vertexIndex, vector<int> adjacentVertices, vector<double> edgeWeights) {
index = vertexIndex;
adj = adjacentVertices;
weights = edgeWeights;
dist = numeric_limits<double>::infinity();
prev = -1; // "undefined" node
opt = false; // unoptimized node
}
};
void dijsktra(vector<DijkstraVertex*> graph, int source, vector<double> &dist, vector<int> &prev) {
vector<DijkstraVertex*> Q(G); // set of unoptimized nodes
G[source]->dist = 0;
while (!Q.empty()) {
sort(Q.begin(), Q.end(), dijkstraDistComp); // sort nodes in Q by dist from source
DijkstraVertex* u = Q.front(); // u = node in Q with lowest dist
u->opt = true;
Q.erase(Q.begin());
if (u->dist == numeric_limits<double>::infinity()) {
break; // all remaining vertices are inaccessible from the source
}
for (int i = 0; i < (signed)u->adj.size(); i++) { // for each neighbour of u not in Q
DijkstraVertex* v = G[u->adj[i]];
if (!v->opt) {
double alt = u->dist + u->weights[i];
if (alt < v->dist) {
v->dist = alt;
v->prev = u->index;
}
}
}
}
for (int i = 0; i < (signed)G.size(); i++) {
assert(G[i] != NULL);
dist.push_back(G[i]->dist); // transfer data to dist for output
prev.push_back(G[i]->prev); // transfer data to prev for output
}
}
There are several things you can improve on this:
implementing the priority queue with sort and erase adds a factor of |E| to the runtime - use the heap functions of the STL to get a log(N) insertion and removal into the queue.
do not put all the nodes in the queue at once but only those where you have discovered a path (which may or may not be the optimal, as you can find an indirect path through nodes in the queue).
creating objects for every node creates unneccessary memory fragmentation. If you care about squeezing out the last 5-10%, you could think about a solution to represent the incidence matrix and other information directly as arrays.
Use priority_queue.
My Dijkstra implementation:
struct edge
{
int v,w;
edge(int _w,int _v):w(_w),v(_v){}
};
vector<vector<edge> > g;
enum color {white,gray,black};
vector<int> dijkstra(int s)
{
int n=g.size();
vector<int> d(n,-1);
vector<color> c(n,white);
d[s]=0;
c[s]=gray;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q; // declare priority_queue
q.push(make_pair(d[s],s)); //push starting vertex
while(!q.empty())
{
int u=q.top().second;q.pop(); //pop vertex from queue
if(c[u]==black)continue;
c[u]=black;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i].v,w=g[u][i].w;
if(c[v]==white) //new vertex found
{
d[v]=d[u]+w;
c[v]=gray;
q.push(make_pair(d[v],v)); //add vertex to queue
}
else if(c[v]==gray && d[v]>d[u]+w) //shorter path to gray vertex found
{
d[v]=d[u]+w;
q.push(make_pair(d[v],v)); //push this vertex to queue
}
}
}
return d;
}