算法导论 所有结点最短路径问题 Johnson

来源:互联网 发布:冬未了 知乎 编辑:程序博客网 时间:2024/06/01 09:46
#include <stdio.h>#include <stdlib.h>#include <limits.h>#include "FIB.h"//图节点  typedef struct VertexNode  {      char name;      VertexNode *p; int key;pFNode pf;int tempKey;}Vertex,*pVertex;    //图  typedef struct   {      int vn;      int **E;      pVertex *V;      int **tempE;  }Graph,*pGraph;  //根据算法导论 图25-6初始化图,Johnson的加入0结点和构造冗余边放在初始化中,这里不动态产生,因为懒 pGraph initGraph()  {      pGraph g=(pGraph)malloc(sizeof(Graph));      g->vn=6;  pVertex v0=(pVertex)malloc(sizeof(Vertex));      v0->name='0';    v0->p=NULL;     pVertex v1=(pVertex)malloc(sizeof(Vertex));      v1->name='1';        v1->p=NULL;      pVertex v2=(pVertex)malloc(sizeof(Vertex));      v2->name='2';        v2->p=NULL;      pVertex v3=(pVertex)malloc(sizeof(Vertex));      v3->name='3';       v3->p=NULL;      pVertex v4=(pVertex)malloc(sizeof(Vertex));      v4->name='4';        v4->p=NULL;      pVertex v5=(pVertex)malloc(sizeof(Vertex));      v5->name='5';       v5->p=NULL;        g->V=(pVertex*)malloc(g->vn*sizeof(pVertex));      g->V[0]=v0;      g->V[1]=v1;      g->V[2]=v2;      g->V[3]=v3;      g->V[4]=v4; g->V[5]=v5;      g->E = (int**)malloc(g->vn*sizeof(int*));  g->tempE= (int**)malloc(g->vn*sizeof(int*));      for(int i=0;i<g->vn;i++)      {          g->E[i]=(int*)malloc(g->vn*sizeof(int));   g->tempE[i]=(int*)malloc(g->vn*sizeof(int));      }      for(int i=0;i<g->vn;i++)      {          for(int j=0;j<g->vn;j++)          { if(i==j)g->E[i][j]=0;elseg->E[i][j]=INT_MAX;          }      }  g->E[0][1]=0;g->E[0][2]=0;g->E[0][3]=0;g->E[0][4]=0;g->E[0][5]=0;    g->E[1][2]=3;      g->E[1][3]=8;  g->E[1][5]=-4;    g->E[2][4]=1;      g->E[2][5]=7;      g->E[3][2]=4;      g->E[4][3]=-5;g->E[4][1]=2;    g->E[5][4]=6;      return g;  }  void relax(pGraph g,int u,int v){//无边,不进行松弛if(g->E[u][v]==INT_MAX)return;int sum,uk=g->V[u]->key,vk=g->V[v]->key,ew=g->E[u][v];//根据规则,加上无穷等于无穷if(uk==INT_MAX || ew==INT_MAX)sum=INT_MAX;elsesum=uk+ew;if(vk>sum){g->V[v]->key=sum;g->V[v]->p=g->V[u];}}void relaxFIB(pGraph g,int u,int v,pFIB h){//无边,不进行松弛if(g->tempE[u][v]==INT_MAX)return;int sum,uk=g->V[u]->tempKey,vk=g->V[v]->tempKey,ew=g->tempE[u][v];//根据规则,加上无穷等于无穷if(uk==INT_MAX || ew==INT_MAX)sum=INT_MAX;elsesum=uk+ew;if(vk>sum){g->V[v]->tempKey=sum;g->V[v]->p=g->V[u];FIB_heap_decreaseKey(h,g->V[v]->pf,sum);}}bool BellmanFord(pGraph g){for(int i=1;i<=g->vn-1;i++){for(int j=0;j<g->vn;j++){for(int k=0;k<g->vn;k++){if(g->E[j][k]<INT_MAX)relax(g,j,k);}}}for(int u=0;u<g->vn;u++){for(int v=0;v<g->vn;v++){if(g->E[u][v]>0){int sum,uk=g->V[u]->key,vk=g->V[v]->key,ew=g->E[u][v];//根据规则,加上无穷等于无穷if(uk==INT_MAX || ew==INT_MAX)sum=INT_MAX;elsesum=uk+ew;if(vk>sum)return false;}}}return true;}void Dijikstra(pGraph g){pFIB h=make_FIB_heap();for(int i=1;i<g->vn;i++){pFNode pf=createNode(g->V[i]->tempKey);g->V[i]->pf=pf;pf->vi=i;FIB_heap_insert(h,pf);}while(h->n>0){pFNode uf=FIB_heap_extract_min(h);int u=uf->vi;for(int v=0;v<g->vn;v++){if(g->tempE[u][v]<INT_MAX)relaxFIB(g,u,v,h);}}}void printKey(pGraph g){for(int i=0;i<g->vn;i++)printf("%d ",g->V[i]->key);printf("\n");}void printD(int **D,int n){for(int i=1;i<n;i++){for(int j=1;j<n;j++){if(D[i][j]<INT_MAX && D[i][j]>INT_MIN)printf("%2d ",D[i][j]);elseprintf("%2c ",'*');}printf("\n");}}int **Johnson(pGraph g){int **D= (int**)malloc(g->vn*sizeof(int*));  int **L= (int**)malloc(g->vn*sizeof(int*));    for(int i=0;i<g->vn;i++)      {          D[i]=(int*)malloc(g->vn*sizeof(int)); L[i]=(int*)malloc(g->vn*sizeof(int));    }  for(int i=0;i<g->vn;i++){if(i==0)g->V[i]->key=0;elseg->V[i]->key=INT_MAX;}bool b=BellmanFord(g);//printKey(g);if(!b){printf("the input graph contains a negative-weight cycle");return NULL;}else{for(int u=0;u<g->vn;u++){for(int v=0;v<g->vn;v++){if(g->E[u][v]<INT_MAX)g->tempE[u][v]=g->E[u][v]+g->V[u]->key-g->V[v]->key;elseg->tempE[u][v]=INT_MAX;}}//printD(g->tempE,g->vn);for(int u=1;u<g->vn;u++){for(int i=1;i<g->vn;i++){g->V[i]->pf=NULL;if(i==u)g->V[i]->tempKey=0;elseg->V[i]->tempKey=INT_MAX;}Dijikstra(g);for(int j=1;j<g->vn;j++){int t=g->V[j]->tempKey;L[u][j]=g->V[j]->tempKey;}}//printD(L,g->vn);for(int u=1;u<g->vn;u++){for(int v=1;v<g->vn;v++){D[u][v]=L[u][v]+g->V[v]->key-g->V[u]->key;}}}return D;}void main(){pGraph g=initGraph();int **D=Johnson(g);printD(D,g->vn);getchar();}

阅读全文
0 0
原创粉丝点击