1. Figure G After the addition of the new node in Figure G, add the new node 0 to the distance between all the original nodes is 0, and form a new edge set E ';
2. Use the Bellman-ford algorithm to process G ' and form the minimum distance d of 0 nodes to each node.
3. If the Bellman-ford algorithm detects that there is a negative weight loop, the hint false and exit, otherwise continue.
4. For vertex v in all G ', set H (v) to this value based on the minimum distance of 0 nodes to V.
5. For all side W (u,v), the weight value is updated to W (u,v) +h (U)-H (v)
6. Dijkstra algorithm for all nodes in Fig G calculates the shortest distance from other vertices d ' [u][v]
(This assumes that the G and W sets are stored separately.) The direct use of G ' can also be possible, since 0 nodes are not up to other nodes, but this obviously wastes computational time. If the weight information exists in G ', it can operate on G ', only skipping the processing of 0 nodes.
7. Original g medium shortest distance d[u][v] = d ' [u][v] +h (v)-H (U)
Some places in the code are not optimized, such as the auxiliary structure vassist in fact, in the Bellman-ford algorithm and Dijkstra algorithm two functions in a slightly different usage, and the member variable in the former only used 2, and relaxation algorithm relax also have a similar situation. The former is a simple reuse, the latter is directly differentiated by name.
The code contains three parts: The Bellman-ford algorithm, the Dijkstra algorithm, the priority series group implemented with two-item heap (Dijkstra algorithm to use). the following is the C language version of the algorithm, test examples and "Introduction to the algorithm" figure 25-1
#include <stdio.h>
#include <stdlib.h>
#define U 65535
#define PARENT (i) ((i-1)/2)
#define LEFT (i) (2* (i) +1)
#define RIGHT (i) (2* (i) +2)
#define N 5
struct Vertex {
int key;
struct vtable *adj;
};
struct Vtable {
int key;//This key is the ordinal number of the vertex array
struct Vertext *v;
int W;
struct vtable *next;
};
struct Vassist {
int D;
int p;
int key;
};
int insert (struct vertex *,int,int,int,int);
int walk (struct vertex *,int,int);
struct vassist *initialize_ss (int,int);
int relaxd (int *,int, int, int);
int relaxb (struct vassist *,int, int, int);
int build_min_heap (struct vassist *,int);
int min_heapify (struct vassist *, int, int);
int heap_extract_min (struct vassist *,int);
int inheap (struct vassist *,int, int);
int heap_decrease (struct vassist *,int, int);
int Dijkstra (struct vertex *,int,int,int * *);
int Bellman_ford (struct vertex *,int*, int,int);
int insert (struct vertex *p,int len,int i,int j,int W) {
struct vtable *q,*prev;
Q = P[i].adj;
printf ("key:%d\n", P[i].key);
prev = NULL;
while (Q!=null) {
if (Q->key = = j) {
printf ("Error:v%d to%d already exist.\n", i,j);
return 0;
}
else {
prev = q;
q=q->next;
}
}
Q = (struct vtable*) malloc (sizeof (struct vtable));
Q->key = j;
Q->w = W;
Q->next = NULL;
if (prev!=null)
Prev->next = q;
Else
P[i].adj = q;
return 1;
}
int walk (struct vertex *p,int len,int i) {
struct vtable *q = P[i].adj;
while (Q!=null) {
printf ("%d,w is%d\n", q->key,q->w);
q=q->next;
}
printf ("\ n");
}
struct vassist *initialize_ss (int size,int s) {
int i;
struct Vassist *va;
VA = (struct vassist *) malloc (size*sizeof (struct vassist));
for (i=0;i<size;i++) {
Va[i].key = i;//I!=key after building a heap
VA[I].D = U;
VA[I].P =-1;
}
VA[S].D = 0;
Return VA;
}
Relax for Dijkstra
int relaxd (int *p,int u,int v,int w) {//w=w (u,v)
if (p[v]>p[u]+w) {
P[V] = p[u]+w;
For simple processing, p uses an array
No parental markers.
If you want to mark with your parents, change p to a custom structure
}
return 1;
}
//relax for Beltman_ford
int relaxb (struct vassist *va,int u,int v,int w) {//w=w (u,v)
if (va[ V].D>VA[U].D+W) {
va[v].d = va[u].d+w;
va[v].p = u;
}
return 1;
}
int Bellman_ford (struct vertex *graph,int *h,int size,int s) {//algorithm requires a negative-weight loop that does not contain source points
int i,j;
struct vtable *p;
struct vassist *va;
va = initialize_ss (size,s);
for (i=1;i<size;i++)
for (j=0;j<size-1; J + +) {
p = Graph[j].adj;
while (p!=null) {
RELAXB (VA,J,P->KEY,P->W);
p=p->next;
}
}
printf ("From%d,\n", s);
for (j=0;j<size;j++)
printf ("To%d:%d\n", J,VA[J].D);
for (j=0;j<size;j++) {//0 node unnecessary
p = Graph[j].adj;
while (P!=null) {
if (va[p->key].d>va[j].d+p->w)
return 0;
p = p->next;
}
}
for (j=1;j<=size;j++)
H[J] = VA[J].D;
Free (VA);
H[0] = 0;
return 1;
}
int build_min_heap (struct vassist *va,int size) {//Build heap
int i;
for (i =size/2-1; i>=0; i--)
Min_heapify (va,i,size);
return 1;
}
int min_heapify (struct vassist *va, int i,int heap_size) {
int l,r,min;
struct Vassist temp;
int tmin = U;
L = left (i);
R = Right (i);
if ((L < heap_size) && (VA[L].D<VA[I].D)) {
min = l;
Tmin = VA[L].D;
}
else {
min = i;
Tmin = VA[I].D;
}
if ((R < heap_size) && (VA[R].D<VA[MIN].D)) {
min = r;
Tmin = VA[R].D;
}
if (!) ( min = i)) {
TEMP.D = VA[MIN].D;
TEMP.P = VA[MIN].P;
Temp.key = Va[min].key;
VA[MIN].D = VA[I].D;
VA[MIN].P = VA[I].P;
Va[min].key = Va[i].key;
VA[I].D = TEMP.D;
VA[I].P = TEMP.P;
Va[i].key = Temp.key;
Min_heapify (va,min,heap_size);
}
return 1;
}
int heap_extract_min (struct vassist *va,int heap_size) {
int min;
if (heap_size<1)
return-1;
min = Va[0].key;
VA[0].P = VA[HEAP_SIZE-1].P;
VA[0].D = VA[HEAP_SIZE-1].D;
Va[0].key = Va[heap_size-1].key;
Heap_size = heap_size-1;
Min_heapify (va,0,heap_size);
return min;
}
int inheap (struct vassist *va,int heap_size,int j) {
int i;
for (i=0;iif (Va[i].key = j)
return i;
return-1;
}
int heap_decrease (struct vassist *va,int i,int key_new) {
struct Vassist temp;
if (KEY_NEW>VA[I].D)
return 0;
VA[I].D = key_new;
while ((i>0) && (va[parent (i)].d > Va[i].d)) {
TEMP.D = VA[I].D;
TEMP.P = VA[I].P;
Temp.key = Va[i].key;
VA[I].D = Va[parent (i)].d;
VA[I].P = Va[parent (i)].p;
Va[i].key = Va[parent (i)].key;
Va[parent (i)].d = TEMP.D;
Va[parent (i)].P = TEMP.P;
Va[parent (i)].key = Temp.key;
i = PARENT (i);
}
return 1;
}
int Dijkstra (struct vertex *graph,int len,int s,int) {
int i,j,heap_size;
struct vtable *q;
struct Vassist *va;
int *p;
p = (int *) malloc (len * sizeof (int));
for (i=0;i<len;i++)
P[i] = U;
P[s] = 0;
Heap_size = Len;
VA = initialize_ss (len,s);
Build_min_heap (va,heap_size);//va is taken to build a heap, the subsequent output distance can not be used again
while (heap_size>0) {
i = Heap_extract_min (va,heap_size);
printf ("node:%d\n", I);
heap_size--;
for (j=0;jprintf ("key:%d,d:%d, in array:%d\n", Va[j].key,va[j].d,p[va[j].key]);
Q = Graph[i].adj;
while (Q!=null) {
J=inheap (Va,heap_size,q->key);
if (j>=0)
if (va[j].d>p[i]+q->w)
Heap_decrease (VA,J,P[I]+Q->W);
Relaxd (P,I,Q->KEY,Q->W)//can actually merge Heap_decreas and relax, but not for interface simplicity
printf ("Relax%d to%d, W is%d\n", i,q->key,q->w);
Q = q->next;
}
for (j=0;jprintf ("key:%d,d:%d, in array:%d\n", Va[j].key,va[j].d,p[va[j].key]);
}
for (i=0;i<len;i++)
printf ("From%d to%d, distance is%d\n", s,i,p[i]);
Free (VA);
for (i=0;i<len;i++) {
Delta[s][i] = P[i];
}
Free (p);
}
int **johnson (struct vertex *g, int n) {
int i,j;
int *h,**delta,**d;
struct vertex *gn;
struct vtable *p;
gn = (struct vertex *) malloc (n*sizeof (struct vertex));
h = (int *) malloc (n*sizeof (int));
Delta = (int**) malloc (n*sizeof (int *));
D = (int**) malloc (n*sizeof (int *));
for (i=0;i<n;i++) {
delta[i]= (int*) malloc (n*sizeof (int));
d[i]= (int*) malloc (n*sizeof (int));
}
for (i=0;i<n;i++)
Gn[i] = G[i];
for (i=1;i<n;i++)
Insert (gn,n,0,i,0);
if (!bellman_ford (gn,h,n,0)) {
printf ("The input graph contains a negative-weight cycle.\n");
return NULL;
}
for (i=0;i<n;i++) {
p = Gn[i].adj;
while (P!=null) {
P->w = p->w+h[i]-h[p->key];
p=p->next;
}
}
for (i=0;i<n;i++)
Walk (Gn,n,i);
printf ("Before dijkstra\n");
for (i=1;i<n;i++) {
Dijkstra (Gn,n,i,delta);
for (j=1;j<n;j++)
D[I][J] = Delta[i][j] + h[j]-h[i];
}
for (i=1;i<n;i++) {
for (j=1;j<n;j++)
printf ("%d\t", D[i][j]);
printf ("\ n");
}
return D;
}
int main () {
int i,j;
int **d;
struct vertex vt[n+1];//as a 0-node entry reserve location
for (i=0;i<n+1;i++) {
Vt[i].adj = NULL;
Vt[i].key = i;
}
Insert (vt,n+1,1,2,3);
Insert (vt,n+1,1,3,8);
Insert (VT,N+1,1,5,-4);
Insert (vt,n+1,2,4,1);
Insert (vt,n+1,2,5,7);
Insert (vt,n+1,3,2,4);
Insert (VT,N+1,4,3,-5);
Insert (vt,n+1,4,1,2);
Insert (vt,n+1,5,4,6);
D = Johnson (vt,n+1);
return 1;
}