【算法导论】24.1 Bellman-Ford 算法

来源:互联网 发布:淘宝爱逛街客户端 编辑:程序博客网 时间:2024/05/29 04:26

本代码为算法导论24.1的C++实现。

#include <iostream>using namespace std;#define  N 5#define INFINITE 0x7fffffff#define WHITE 1#define GRAY 2#define BLACK 3//顶点结点结构  struct Vertex  {  Vertex * next;/*指向下一个顶点*/int id;/*节点的标志*/int weight;/*节点的权值,临界表表头到此元素上边的权值*/    Vertex():next(NULL),id(0){}  };  //图结构struct Graph{Vertex *Adj[N+1];//N个顶点及邻接点头指针int p[N+1];//指向遍历树节点的父结点 int d[N+1];/*节点的最短路径权值的上界*/Graph(){         for(int i = 1; i <= N; i++)  {            Adj[i] = new Vertex;d[i] = 0;p[i] = 0;}}~Graph()      {          for(int i = 1; i <= N; i++)              delete Adj[i];      }  };void Print(Graph *g);bool Init(Graph *g);bool InsertEdge(Graph *g , int start,int end,int weight);bool InitializeSingleSource(Graph *g,int s);bool Relax(Graph *g,int u,int v,int weight);bool Relax(Graph *g,int u,int v);int  Weight(const Graph *g,int u,int v);/*start边开始节点,end边结束节点,weight边权值*///插入边bool InsertEdge(Graph *g , int start,int end,int weight){Vertex* v = new Vertex();v->id = end;v->weight = weight;if(g->Adj[start]->next == NULL){/*如果不存在临界表的头结点列表中,则插入*/Vertex* s = new Vertex();s->id = start;g->Adj[start] = s;}Vertex* tmp = g->Adj[start];while(tmp->next){tmp = tmp->next;}tmp->next =v;return true;}/*初始化临接表表示的图,有向图。*/bool Init(Graph *g){InsertEdge(g,1,2,6);InsertEdge(g,1,4,7);InsertEdge(g,2,3,5);InsertEdge(g,2,4,8);InsertEdge(g,2,5,-4);InsertEdge(g,3,2,-2);InsertEdge(g,4,3,-3);InsertEdge(g,4,5,9);InsertEdge(g,5,1,2);InsertEdge(g,5,3,7);return true;}/*取得两个两个节点连接的边的权重*/int Weight(const Graph *g,int u,int v){Vertex * t = g->Adj[u]->next;while(t){if(t->id == v){return t->weight;}t = t->next;}return 0;}bool Relax(Graph *g,int u,int v,int weight){if(g->d[v] > (g->d[u] + Weight(g,u,v))){g->d[v] = g->d[u] + Weight(g,u,v);g->p[v] = u;}return true;}/*对边进行松弛操作*/bool Relax(Graph *g,int u,int v){Relax(g,u,v,Weight(g,u,v));return false;}/*最短路径估计和前驱化进行初始化s 源顶点*/bool InitializeSingleSource(Graph *g,int s){for(int i=1;i<=N;i++){g->d[i] = INFINITE;g->p[i] = 0;}g->d[s] = 0;return true;}/*单源最短路径的Bellman-Ford算法*/bool BellmanFord(Graph *g,int s){InitializeSingleSource(g,s);for(int i=1;i<N;i++){/*对每个边进行N-1次松弛操作*/for(int j=1;j<=N;j++){Vertex * t = g->Adj[j]->next;while(t){Relax(g,j,t->id);t = t->next;}}}for(int i=1;i<=N;i++){/*如果包含从原点可达的负权回路,返回FALSE*/Vertex * t = g->Adj[i]->next;while(t){if(g->d[t->id] > (g->d[i] + Weight(g,i,t->id))){return false;}t = t->next;}}return true;}/*开始顶点 1顶点  最短路径1       02       23       44       75       -2*/int main(int argc,char * argv[]){//构造一个空的图Graph *g = new Graph;Init(g);BellmanFord(g,1);for(int i=1;i<=N;i++){std::cout<<i<<"\t"<<g->d[i]<<std::endl;}delete g;getchar();return 0;}