/*
* OLGraph.h
*
* Created on: Oct 19, 2015
* Author: chris
*/
#ifndef OLGRAPH_H_
#define OLGRAPH_H_
#include<iostream>
#include<limits>
#define MAX_VERTEX_NUM 20
#define INF INT_MAX
struct InfoType{
int weight;
InfoType(): weight(0) {}
};
struct ArcBox{
int from, to;
InfoType *info;
ArcBox *nextin, *nextout;
ArcBox():from(0), to(0),
info(NULL), nextin(NULL), nextout(NULL) {}
};
typedef int VertexType;
struct VexNode{
VertexType data;
ArcBox arcin, arcout;
VexNode():data(0){}
};
struct OLGraph{
VexNode* vexlist;
int vexnum;
OLGraph(): vexlist(NULL), vexnum(0) {}
};
struct Activity{
int from, to;
int dut;
int ee, el;
Activity(): from(0), to(0),
dut(0), ee(0), el(0) {}
};
bool OLGraphCreate(OLGraph & G, int vexnum);
void OLGraphDestroy(OLGraph & G);
bool OLGraphBuild(OLGraph & G);
bool OLGraphAddArc(OLGraph & G, int from, int to, InfoType& info);
bool OLGraphGetArc(OLGraph & G, int from, int to, InfoType& info);
bool OLGraphChgArc(OLGraph & G, int from, int to, InfoType& info);
bool OLGraphDelArc(OLGraph & G, int from, int to);
int OLGraphInDeg(OLGraph & G, int vex);
int OLGraphOutDeg(OLGraph & G, int vex);
int OLGraphPreVex(OLGraph & G, int vex, int *& pre);
int OLGraphSucVex(OLGraph & G, int vex, int *& suc);
bool OLGraphGetDist(OLGraph & G, int from, int to, int& dist);
bool OLGraphDFSTraverse(OLGraph & G, int root, bool(*visit)(VexNode*));
bool OLGraphBFSTraverse(OLGraph & G, int root, bool(*visit)(VexNode*));
bool OLGraphLabelSCC(OLGraph & G, int *& scc_label);
bool OLGraphArticul(OLGraph & G, int & num, int *& articul);
bool OLGraphTopoSort(OLGraph & G, int*& result);
bool OLGraphTopoSort(OLGraph & G, int*& result, int*& ve);
bool OLGraphCriticalPath(OLGraph & G, int& num ,Activity*& crtpath);
bool OLGraphDijkstra(OLGraph & G, int src, int*& dist, int*& pre);
bool OLGraphBellmanFord(OLGraph & G, int src, int *& dist, int*& pre);
bool OLGraphWarshall(OLGraph & G, int**& dist, int**& pre);
void OLGraphWalkThrough(OLGraph & G);
#endif /* OLGRAPH_H_ */
/*
* OLGraph.cpp
*
* Created on: Oct 19, 2015
* Author: chris
*/
#include"OLGraph.h"
#include<iostream>
using namespace std;
bool OLGraphCreate(OLGraph & G, int vexnum)
{
VexNode * temp = new VexNode[vexnum];
if(!temp) return false;
G.vexlist = temp;
G.vexnum = vexnum;
for(int i = 0; i < vexnum; ++i)
G.vexlist[i].data = i;
return true;
}
void OLGraphDestroy(OLGraph & G)
{
if(!G.vexlist) return;
for(int i = 0; i < G.vexnum; ++i) {
ArcBox * opcur = G.vexlist[i].arcout.nextout, *tp = NULL;
while(opcur) {
tp = opcur;
opcur = opcur->nextout;
delete tp->info;
delete tp;
}
}
delete G.vexlist;
G.vexnum = 0;
}
bool OLGraphBuild(OLGraph & G)
{
OLGraphDestroy(G);
int vexnum = 0;
cout << "Enter the number of vertices: "; cout.flush();
cin >> vexnum;
if(!OLGraphCreate(G, vexnum))
return false;
int arcnum = 0;
cout << "Enter the number of arcs: "; cout.flush();
cin >> arcnum;
for(int i = 0; i < arcnum; ++i) {
int from, to;
InfoType info;
cout << "Enter from, to, and info: "; cout.flush();
cin >> from >> to >> info.weight;
if(!OLGraphAddArc(G, from, to, info)) {
cout << "Add Arc failed." << endl;
}
}//end for
return true;
}
bool OLGraphAddArc(OLGraph & G, int from, int to, InfoType& info)
{
//in range.
if(from < 0 || from >= G.vexnum || to < 0 || to >= G.vexnum)
return false;
//avoid rep.
if(OLGraphGetArc(G, from, to, info))
return false;
//alloc.
ArcBox * arc = new ArcBox;
if(!arc) return false;
arc->info = new InfoType;
if(!arc->info) {
delete arc;
return false;
}
//load.
arc->from = from;
arc->to = to;
*arc->info = info;
//insert;
ArcBox * oprior = &G.vexlist[from].arcout,
* iprior = &G.vexlist[to].arcin;
while(oprior->nextout && oprior->nextout->to < to)
oprior = oprior->nextout;
arc->nextout = oprior->nextout;
oprior->nextout = arc;
while(iprior->nextin && iprior->nextin->from < from)
iprior = iprior->nextin;
arc->nextin = iprior->nextin;
iprior->nextin = arc;
return true;
}
bool OLGraphGetArc(OLGraph & G, int from, int to, InfoType& info)
{
//in range.
if(from < 0 || from >= G.vexnum || to < 0 || to >= G.vexnum)
return false;
ArcBox * opcur = G.vexlist[from].arcout.nextout;
while(opcur && opcur->to != to)
opcur = opcur->nextout;
if(opcur) {
info = *opcur->info;
return true;
} else
return false;
}
bool OLGraphChgArc(OLGraph & G, int from, int to, InfoType& info)
{
if(from < 0 || from >= G.vexnum || to < 0 || to >= G.vexnum)
return false;
ArcBox * opcur = G.vexlist[from].arcout.nextout;
while(opcur && opcur->to != to)
opcur = opcur->nextout;
if( opcur ) {
*opcur->info = info;
return true;
} else
return false;
}
bool OLGraphDelArc(OLGraph & G, int from, int to)
{
if(from < 0 || from >= G.vexnum || to < 0 || to >= G.vexnum)
return false;
ArcBox * oprior = &G.vexlist[from].arcout,
* iprior = &G.vexlist[to].arcin;
//find.
while(oprior->nextout && oprior->nextout->to != to)
oprior = oprior->nextout;
if(!oprior) return false;
while(iprior->nextin && iprior->nextin->from != from)
iprior = iprior->nextin;
ArcBox * pcur = oprior->nextout;
//detach
oprior->nextout = pcur->nextout;
iprior->nextin = pcur->nextin;
delete pcur->info;
delete pcur;
return true;
}
int OLGraphInDeg(OLGraph & G, int vex)
{
if(vex < 0 || vex >= G.vexnum)
return -1;
ArcBox * pcur = G.vexlist[vex].arcin.nextin;
int cnt = 0;
while(pcur) {
++cnt;
pcur = pcur->nextin;
}
return cnt;
}
int OLGraphOutDeg(OLGraph & G, int vex)
{
if(vex < 0 || vex >= G.vexnum)
return -1;
ArcBox * pcur = G.vexlist[vex].arcout.nextout;
int cnt = 0;
while(pcur) {
++cnt;
pcur = pcur->nextout;
}
return cnt;
}
int OLGraphPreVex(OLGraph & G, int vex, int *& pre)
{
int indeg = 0;
if((indeg = OLGraphInDeg(G, vex)) == -1)
return 0;
pre = new int[indeg];
if(!pre) return 0;
ArcBox * ipcur = G.vexlist[vex].arcin.nextin;
int cnt = 0;
while(ipcur) {
pre[cnt++] = ipcur->from;
ipcur = ipcur->nextin;
}
return cnt;
}
int OLGraphSucVex(OLGraph & G, int vex, int *& suc)
{
int outdeg = 0;
if((outdeg = OLGraphOutDeg(G, vex)) == -1)
return 0;
suc = new int[outdeg];
if(!suc) return 0;
ArcBox * opcur = G.vexlist[vex].arcout.nextout;
int cnt = 0;
while(opcur) {
suc[cnt++] = opcur->to;
opcur = opcur->nextout;
}
return cnt;
}
bool OLGraphGetDist(OLGraph & G, int from, int to, int & dist)
{
if(from < 0 || from >= G.vexnum || to < 0 || to >= G.vexnum)
return false;
dist = INF;
ArcBox * opcur = G.vexlist[from].arcout.nextout;
while(opcur) {
if(opcur->to == to)
dist = opcur->info->weight;
opcur = opcur->nextout;
}
return true;
}
#define STACK_SIZE 512
bool OLGraphDFSTraverse(OLGraph & G, int root, bool(*visit)(VexNode*))
{
if(root < 0 || root >= G.vexnum)
return false;
bool* visited = new bool[G.vexnum];
if(!visited) return false;
for(int i = 0; i < G.vexnum; ++i)
visited[i] = false;
int* stk = new int[STACK_SIZE];
if(!stk) {
delete visited;
return false;
}
int top = 0;
stk[top++] = root;
while(top > 0) {
int cur = stk[--top];
visited[cur] = true;
if(!visit(G.vexlist + cur))
return false;
ArcBox* opcur = G.vexlist[cur].arcout.nextout;
while(opcur) {
if(!visited[opcur->to])
stk[top++] = opcur->to;
opcur = opcur->nextout;
}
}//dfs
delete stk;
delete visited;
return true;
}
#define QUEUE_SIZE 512
bool OLGraphBFSTraverse(OLGraph & G, int root, bool(*visit)(VexNode*))
{
if(root < 0 || root >= G.vexnum)
return false;
bool* visited = new bool[G.vexnum];
if(!visited) return false;
for(int i = 0; i < G.vexnum; ++i)
visited[i] = true;
int* queue = new int[QUEUE_SIZE];
if(!queue) {
delete visited;
return false;
}
int front = 0, rear = 0;
queue[rear++] = root;
while(front != rear) {
int cur = queue[front];
front = (front + 1) % QUEUE_SIZE;
visited[cur] = true;
if(!visit(G.vexlist + cur))
return false;
ArcBox* opcur = G.vexlist[cur].arcout.nextout;
while(opcur) {
if(!visited[opcur->to]) {
queue[rear] = opcur->to;
rear = (rear + 1) % QUEUE_SIZE;
}
opcur = opcur->nextout;
}
}//bfs.
return true;
}
//Tarjon algo
bool OLGraphLabelSCC(OLGraph & G, int*& scc_label)
{
scc_label = new int[G.vexnum];
int* visited = new int[G.vexnum];
int* stk = new int[STACK_SIZE];
bool* done = new bool[G.vexnum];
if(!scc_label || !visited || !stk || !done) {
if(scc_label) delete scc_label;
if(visited) delete visited;
if(stk) delete stk;
if(done) delete done;
return false;
}
int top = 0;
for(int i = 0; i < G.vexnum; ++i)
scc_label[i] = visited[i] = 0;
int cnt = 0;
for(int root = 0; root < G.vexnum; ++root) {
if(visited[root] != 0) //visited
continue;
//dfs from root.
top = 0;
stk[top++] = root;
done[root] = false;
while(top > 0) {
int cur = stk[top-1];
if(done[cur]) {
--top;
continue;
}
if(visited[cur] == 0) { // not visited.
scc_label[cur] = visited[cur] = ++cnt;
//expand from cur.
ArcBox* opcur = G.vexlist[cur].arcout.nextout;
while( opcur ) {
int adjvex = opcur->to;
if(scc_label[adjvex] == 0) {
stk[top++] = adjvex;
done[adjvex] = false;
}
opcur = opcur->nextout;
}
} // end if not visited
else {
--top;
ArcBox* opcur = G.vexlist[cur].arcout.nextout;
while(opcur) {
int adjvex = opcur->to;
// reachability update.
if(visited[adjvex] >= visited[root] // in the same component.
&& scc_label[cur] > scc_label[adjvex] )
scc_label[cur] = scc_label[adjvex];
opcur = opcur->nextout;
}
done[cur] = true;
} // end if visited
}//end dfs
}//end for
delete visited;
delete stk;
delete done;
return true;
}
bool OLGraphArticul(OLGraph & G, int & num, int *& articul)
{
//alloc
articul = new int[G.vexnum];
int* low = new int[G.vexnum];
int* visited = new int[G.vexnum];
int* stk = new int[STACK_SIZE];
bool* done = new bool[G.vexnum];
if( !articul || !low || !visited || !stk || !done) {
if(articul) delete articul;
if(low) delete low;
if(visited) delete visited;
if(stk) delete stk;
if(done) delete done;
return false;
}
int top = 0;
int cnt = 0;
num = 0;
//init
for(int i = 0; i < G.vexnum; ++i)
low[i] = visited[i] = 0;
for(int root = 0; root < G.vexnum; ++root) {
if(visited[root] != 0) //visited.
continue;
//dfs from root.
top = 0;
stk[top++] = root;
done[root] = false;
int depth = 0;
int num_of_subT = 0;
while(top > 0) {
int cur = stk[top-1];
if(done[cur]) {
--top;
continue;
} // avoid rep.
if(visited[cur] == 0) { //not visited.
low[cur] = visited[cur] = ++cnt; //visit
if(++depth == 2)
++num_of_subT;
//expand from cur.
ArcBox * opcur = G.vexlist[cur].arcout.nextout;
while(opcur) {
int adjvex = opcur->to;
if(visited[adjvex] == 0) {
stk[top++] = adjvex;
done[adjvex] = false;
}
opcur = opcur->nextout;
}
} // end if not visited.
else {
--top; //pop
done[cur] = true;
bool found = false;
ArcBox * opcur = G.vexlist[cur].arcout.nextout;
while( opcur ) {
int adjvex = opcur->to;
// adjacency update.
// forward arc
if( visited[adjvex] > visited[cur] // adjvex is child of cur.
&& low[cur] > low[adjvex] )
low[cur] = low[adjvex]; // update.
// backward arc
else if( visited[adjvex] >= visited[root]
&& low[cur] > visited[adjvex] )
low[cur] = visited[adjvex];
if(cur != root && low[adjvex] >= visited[cur] && !found) {
//nonroot articul found.
found = true;
articul[num++] = cur;
}
opcur = opcur->nextout;
}//endw.
--depth;
}//end if visited.
}//end dfs
//check root.
if(num_of_subT >= 2)
articul[num++] = root;
}//end for
delete low;
delete visited;
delete stk;
delete done;
return true;
}
bool OLGraphTopoSort(OLGraph & G, int*& result)
{
int* ve = NULL;
if(OLGraphTopoSort( G, result, ve)) {
delete ve;
return true;
}
return false;
}
bool OLGraphTopoSort(OLGraph & G, int*& result, int*& ve)
{
result = new int[G.vexnum];
ve = new int[G.vexnum];
int* indeg = new int[G.vexnum];
int* stk = new int[STACK_SIZE];
if( !result || !ve || !indeg || !stk ) {
if(result) delete result;
if(ve) delete ve;
if(indeg) delete indeg;
if(stk) delete stk;
return false;
}
int top = 0;
//init indeg and ve.
for(int i = 0; i < G.vexnum; ++i) {
indeg[i] = OLGraphInDeg(G, i);
ve[i] = 0;
if(indeg[i] == 0) stk[top++] = i;
}
int cnt = 0;
while(top > 0) {
int cur = stk[--top];
result[cnt++] = cur;
//expand
ArcBox* opcur = G.vexlist[cur].arcout.nextout;
while(opcur) {
int adjvex = opcur->to;
if(--indeg[adjvex] == 0)
stk[top++] = adjvex;
if(ve[cur] + opcur->info->weight > ve[adjvex])
ve[adjvex] = ve[cur] + opcur->info->weight;
opcur = opcur->nextout;
} // endw opcur
}//endw top.
delete indeg;
delete stk;
if(cnt < G.vexnum) {
delete result;
delete ve;
return false;
}
else return true;
}
bool OLGraphCriticalPath(OLGraph & G, int& num ,Activity*& crtpath)
{
int *stk = NULL, *ve = NULL;
if(!OLGraphTopoSort(G, stk, ve))
return false;
// init vl.
int *vl = new int[G.vexnum];
if( !vl ) {
delete stk;
delete ve;
if(vl) delete vl;
}
for(int i = 0; i < G.vexnum; ++i)
vl[i] = ve[G.vexnum-1];
int top = G.vexnum; // top of stk
while(top > 0) {
int cur = stk[--top];
ArcBox * opcur = G.vexlist[cur].arcout.nextout;
while(opcur) {
int adjvex = opcur->to;
if(vl[cur] > vl[adjvex] - opcur->info->weight)
vl[cur] = vl[adjvex] - opcur->info->weight;
opcur = opcur->nextout;
} // endw opcur
} // endw top
// cnt critical activity
num = 0;
for(int i = 0; i < G.vexnum; ++i) {
ArcBox * opcur = G.vexlist[i].arcout.nextout;
while(opcur) {
int adjvex = opcur->to;
int ee = ve[i], el = vl[adjvex] - opcur->info->weight;
if( ee == el ) ++num;
opcur = opcur->nextout;
}//endif opcur
}//endf
crtpath = new Activity[num];
int cnt = 0;
if(crtpath) {
//record
for(int i = 0; i < G.vexnum; ++i) {
ArcBox * opcur = G.vexlist[i].arcout.nextout;
while(opcur) {
int adjvex = opcur->to;
int ee = ve[i], el = vl[adjvex] - opcur->info->weight;
if( ee == el ) {
crtpath[cnt].from = i;
crtpath[cnt].to = adjvex;
crtpath[cnt].dut = opcur->info->weight;
crtpath[cnt].ee = ee;
crtpath[cnt].el = el;
++cnt;
}
opcur = opcur->nextout;
}
}//endf
delete stk;
delete ve;
delete vl;
return true;
}//endif
delete stk;
delete ve;
delete vl;
return false;
}
bool OLGraphDijkstra(OLGraph & G, int src, int*& dist, int*& pre)
{
if(src < 0 || src >= G.vexnum)
return false;
dist = new int[G.vexnum];
pre = new int[G.vexnum];
bool* visited = new bool[G.vexnum];
if( !dist || !pre || !visited ) {
if(dist) delete dist;
if(pre) delete pre;
if(visited) delete visited;
return false;
}
//init
for(int i = 0; i < G.vexnum; ++i) {
dist[i] = INF;
pre[i] = -1;
visited[i] = false;
}
dist[src] = 0;
for(int k = 0; k < G.vexnum-1; ++k) {
//extract min
int m = 0;
for(int i = 1; i < G.vexnum; ++i)
if(visited[m] || (!visited[i] && dist[m] > dist[i]))
m = i;
if(dist[m] == INF) break;
//visit.
visited[m] = true;
//relax.
ArcBox* opcur = G.vexlist[m].arcout.nextout;
while(opcur) {
int adjvex = opcur->to;
int wgt = opcur->info->weight;
if( !visited[adjvex] // not yet visited.
&& wgt != INF // reachable.
&& dist[adjvex] > dist[m] + wgt) {
dist[adjvex] = dist[m] + wgt;
pre[adjvex] = m;
}//endif
opcur = opcur->nextout;
}//endw opcur
}// endfor k
delete visited;
return true;
}
bool OLGraphBellmanFord(OLGraph & G, int src, int *& dist, int*& pre)
{
if(src < 0 || src >= G.vexnum)
return false;
//alloc
dist = new int[G.vexnum];
pre = new int[G.vexnum];
bool* visited = new bool[G.vexnum];
if( !dist || !pre || !visited ) {
if(dist) delete dist;
if(pre) delete pre;
if(visited) delete visited;
return false;
}
//init
for(int i = 0; i < G.vexnum; ++i) {
dist[i] = INF;
pre[i] = -1;
visited[i] = false;
}
dist[src] = 0;
for(int k = 0; k < G.vexnum-1; ++k) { //k-steps
int changed = false;
// for every arc.
for(int i = 0; i < G.vexnum; ++i) {
ArcBox* opcur = G.vexlist[i].arcout.nextout;
while(opcur) {
int j = opcur->to;
// relax
if( dist[i] != INF // i is reachable
&& opcur->info->weight != INF // j is reachable from i
&& dist[i] + opcur->info->weight < dist[j]) {
dist[j] = dist[i] + opcur->info->weight;
pre[j] = i;
changed = true;
}
opcur = opcur->nextout;
}//endw opcur
}//endfor i
if(!changed) break;
}//endfor k
//Check weights
// for(int i = 0; i < G.vexnum; ++i) {
// ArcBox* opcur = G.vexlist[i].arcout.nextout;
// while(opcur) {
// int j = opcur->to;
// // relax
// if( dist[i] != INF // i is reachable
// && opcur->info->weight != INF // j is reachable from i
// && dist[i] + opcur->info->weight < dist[j] ) {
// //negative weight cycle detected.
// delete dist;
// delete pre;
// return false;
// }
// opcur = opcur->nextout;
// }//endw opcur
// }//endfor i
//
return true;
}
bool OLGraphWarshall(OLGraph & G, int**& dist, int**& pre)
{
//alloc
dist = new int*[G.vexnum]; // shortest path weights
pre = new int*[G.vexnum]; // predecessor matrix.
if(!dist || !pre) {
if(dist) delete dist;
if(pre) delete pre;
return false;
}
for(int i = 0; i < G.vexnum; ++i) {
dist[i] = new int[G.vexnum];
pre[i] = new int[G.vexnum];
if(!dist[i] || !pre[i]) {
for(int j = 0; j <= i; ++j) {
if(dist[i]) delete dist[i];
if(pre[i]) delete pre[i];
}
delete dist; delete pre;
return false;
}//dispose.
}//endfor i
//init
for(int i = 0; i < G.vexnum; ++i) {
for(int j = 0; j < G.vexnum; ++j) {
if(i == j) {
dist[i][j] = 0;
pre[i][j] = -1;
} else {
dist[i][j] = INF;
pre[i][j] = -1;
}
}
}//endif
for(int i = 0; i < G.vexnum; ++i) {
ArcBox* opcur = G.vexlist[i].arcout.nextout;
while(opcur) {
int j = opcur->to;
if(opcur->info->weight != INF) {
dist[i][j] = opcur->info->weight;
pre[i][j] = i;
}
opcur = opcur->nextout;
}
}//end init.
for(int k = 0; k < G.vexnum; ++k) { // k th intermediate vertex.
for(int i = 0; i < G.vexnum; ++i) {
for(int j = 0; j < G.vexnum; ++j) {
if( dist[i][k] != INF // k reachable from i
&& dist[k][j] != INF // j reachable from k
&& dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
pre[i][j] = pre[k][j];
}
}//endfor j
}//endfor i
}//endfor k
return true;
}
void OLGraphWalkThrough(OLGraph & G)
{
int vex = 0;
bool running = true;
while(running) {
cout << "Current pos: " << vex << endl;
int * pre = NULL, * suc = NULL;
int indeg = 0, outdeg = 0;
if((indeg = OLGraphPreVex(G, vex, pre)) > 0) {
cout << "Pre Vex are: ";
for(int i = 0; i < indeg; ++i)
cout << pre[i] << " ";
cout << endl;
}
if((outdeg = OLGraphSucVex(G, vex, suc)) > 0) {
cout << "Suc Vex are: ";
for(int i = 0; i < outdeg; ++i)
cout << suc[i] << " ";
cout << endl;
}
cout.flush();
int ans = 0;
do{
cout << "Enter the next vex: "; cout.flush();
cin >> ans;
if((ans >= 0 && ans < G.vexnum) || ans == -1)
break;
}while(true);
if(ans == -1)
running = false;
else
vex = ans;
}//endw
system("pause");
}
/*
* Main.cpp
*
* Created on: Oct 19, 2015
* Author: chris
*/
#include<iostream>
#include"OLGraph.h"
#include<iomanip>
using namespace std;
int main(void)
{
OLGraph g;
if(OLGraphBuild(g)) {
int **dist, **pre;
if(OLGraphWarshall(g, dist, pre)) {
cout << "dist: " << endl;
for(int i = 0; i < g.vexnum; ++i) {
for(int j = 0; j < g.vexnum; ++j) {
if(dist[i][j] != INF)
cout << setw(3) << dist[i][j] << " ";
else
cout << "INF ";
}
cout << endl;
}
cout << endl;
cout << "pre: " << endl;
for(int i = 0; i < g.vexnum; ++i) {
for(int j = 0; j < g.vexnum; ++j) {
if(pre[i][j] != -1)
cout << setw(3) << pre[i][j] << " ";
else
cout << "NIL ";
}
cout << endl;
}
cout << endl;
for(int i = 0; i < g.vexnum; ++i) {
delete dist[i];
delete pre[i];
}
delete dist;
delete pre;
}
// int* dist = NULL, *pre = NULL;
// if(OLGraphBellmanFord(g, 0, dist, pre)) {
// cout << "dist: " << endl;
// for(int i = 0; i < g.vexnum; ++i)
// cout << dist[i] << " ";
// cout << endl;
// cout << "pre: " << endl;
// for(int i = 0; i < g.vexnum; ++i)
// cout << pre[i] << " ";
// cout << endl;
//
// delete dist;
// delete pre;
// }//endif
}
OLGraphDestroy(g);
system("pause");
return 0;
}