#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;
else
g->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;
else
sum=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;
else
sum=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;
else
sum=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]);
else
printf("%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;
else
g->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;
else
g->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;
else
g->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();
}
算法导论 所有结点最短路径问题 Johnson
最新推荐文章于 2022-04-15 13:44:33 发布