(1)从某个源点到其余各顶点的最短路径
Dijkstra的代码如下:
头文件:
#define
INFINITY 10000
#define MAX_VERTEX_NUM 20
typedef int InfoType;
typedef char VertexType;
typedef int VRType;
typedef enum ... {DG, DN, UDG, UDN} GraphKind;
typedef struct ArcCell ... {
VRType adj;
InfoType *info;
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct ... {
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum, arcnum;
GraphKind kind;
} MGraph;
int weight[][ 6 ] = ... {
...{0, INFINITY, 10, INFINITY, 30, 100},
...{INFINITY, 0, 5, INFINITY, INFINITY, INFINITY},
...{INFINITY, INFINITY, 0, 50, INFINITY, INFINITY},
...{INFINITY, INFINITY, INFINITY, 0, INFINITY, 10},
...{INFINITY, INFINITY, INFINITY, 20, 0, 60},
...{INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 0}
} ;
// #define INPUT 1
#define MAX_VERTEX_NUM 20
typedef int InfoType;
typedef char VertexType;
typedef int VRType;
typedef enum ... {DG, DN, UDG, UDN} GraphKind;
typedef struct ArcCell ... {
VRType adj;
InfoType *info;
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct ... {
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum, arcnum;
GraphKind kind;
} MGraph;
int weight[][ 6 ] = ... {
...{0, INFINITY, 10, INFINITY, 30, 100},
...{INFINITY, 0, 5, INFINITY, INFINITY, INFINITY},
...{INFINITY, INFINITY, 0, 50, INFINITY, INFINITY},
...{INFINITY, INFINITY, INFINITY, 0, INFINITY, 10},
...{INFINITY, INFINITY, INFINITY, 20, 0, 60},
...{INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 0}
} ;
// #define INPUT 1
源文件:
#include
"
graph_dj.h
"
#include " stdio.h "
#include " stdlib.h "
void createDG(MGraph & g) ... {}
void createDN(MGraph & g) ... {}
void createUDG(MGraph & g) ... {}
int locate(MGraph g, char name) ... {
for(int i = 0; i < g.vexnum; i++)...{
if(name == g.vexs[i])...{
return i;
}
}
return -1;
}
void createUDN(MGraph & g) ... {
#ifdef INPUT
printf("input the number of vertex and arcs: ");
scanf("%d %d", &g.vexnum, &g.arcnum);
fflush(stdin);
#else
printf("input the number of vertex: ");
scanf("%d", &g.vexnum);
fflush(stdin);
#endif
int i = 0, j = 0, k = 0;
printf("input the name of vertex: ");
for(i = 0; i < g.vexnum; i++)...{
scanf("%c", &g.vexs[i]);
fflush(stdin);
}
for(i = 0; i < g.vexnum; i++)...{
for(j = 0; j < g.vexnum; j++)...{
g.arcs[i][j].adj = INFINITY;
g.arcs[i][j].info = NULL;
}
}
#ifdef INPUT
char v1, v2;
int w;
printf("input the %d arcs v1 v2 and weight: ", g.arcnum);
for(k = 0; k < g.arcnum; k++)...{
scanf("%c %c %d", &v1, &v2, &w);
fflush(stdin);
i = locate(g, v1);
j = locate(g, v2);
g.arcs[i][j].adj = w;
}
#else
printf("now constructing the matrix of graph... ");
for(i = 0; i < g.vexnum; i++)...{
for(j = 0; j < g.vexnum; j++)...{
g.arcs[i][j].adj = weight[i][j];
}
}
#endif
}
void printGraph(MGraph g) ... {
for(int i = 0; i < g.vexnum; i++)...{
for(int j = 0; j < g.vexnum; j++)...{
printf("%d ", g.arcs[i][j].adj);
}
printf(" ");
}
}
void createGragh(MGraph & g) ... {
printf("please input the type of graph: ");
scanf("%d", &g.kind);
switch(g.kind)...{
case DG:
createDG(g);
break;
case DN:
createDN(g);
break;
case UDG:
createUDG(g);
break;
case UDN:
createUDN(g);
printGraph(g);
break;
}
}
void dijkstra(MGraph g) ... {
int *dist = (int *)malloc(sizeof(int) * g.vexnum);
int *parent = (int *)malloc(sizeof(int) * g.vexnum);
int *final = (int *)malloc(sizeof(int) * g.vexnum);
int i, j, k, cost;
//init the arrays
for(i = 0; i < g.vexnum; i++)...{
dist[i] = g.arcs[0][i].adj;
parent[i] = 0;
final[i] = 0;
}
//join the start 0.
final[0] = 1;
for(i = 1; i < g.vexnum; i++)...{
//get the min of dist
cost = INFINITY;
k = -1;
for(j = 1; j < g.vexnum; j++)...{
if(dist[j] < cost && final[j] == 0)...{
cost = dist[j];
k = j;
}
}
if(k > 0)...{
//join the k node
final[k] = 1;
//update the dist
for(int t = 1; t < g.vexnum; t++)...{
if(final[t] == 0)...{
if(dist[t] > dist[k] + g.arcs[k][t].adj)...{
dist[t] = dist[k] + g.arcs[k][t].adj;
parent[t] = k;
}
}
}
}
}
//print the dist and parent array
printf("the shortest path from %c is as follows: ", g.vexs[0]);
for(i = 0; i < g.vexnum; i++)...{
printf("%c via %c's dist is %d ",
g.vexs[i], g.vexs[parent[i]], dist[i]);
}
}
void main() ... {
MGraph g;
createGragh(g);
dijkstra(g);
}
#include " stdio.h "
#include " stdlib.h "
void createDG(MGraph & g) ... {}
void createDN(MGraph & g) ... {}
void createUDG(MGraph & g) ... {}
int locate(MGraph g, char name) ... {
for(int i = 0; i < g.vexnum; i++)...{
if(name == g.vexs[i])...{
return i;
}
}
return -1;
}
void createUDN(MGraph & g) ... {
#ifdef INPUT
printf("input the number of vertex and arcs: ");
scanf("%d %d", &g.vexnum, &g.arcnum);
fflush(stdin);
#else
printf("input the number of vertex: ");
scanf("%d", &g.vexnum);
fflush(stdin);
#endif
int i = 0, j = 0, k = 0;
printf("input the name of vertex: ");
for(i = 0; i < g.vexnum; i++)...{
scanf("%c", &g.vexs[i]);
fflush(stdin);
}
for(i = 0; i < g.vexnum; i++)...{
for(j = 0; j < g.vexnum; j++)...{
g.arcs[i][j].adj = INFINITY;
g.arcs[i][j].info = NULL;
}
}
#ifdef INPUT
char v1, v2;
int w;
printf("input the %d arcs v1 v2 and weight: ", g.arcnum);
for(k = 0; k < g.arcnum; k++)...{
scanf("%c %c %d", &v1, &v2, &w);
fflush(stdin);
i = locate(g, v1);
j = locate(g, v2);
g.arcs[i][j].adj = w;
}
#else
printf("now constructing the matrix of graph... ");
for(i = 0; i < g.vexnum; i++)...{
for(j = 0; j < g.vexnum; j++)...{
g.arcs[i][j].adj = weight[i][j];
}
}
#endif
}
void printGraph(MGraph g) ... {
for(int i = 0; i < g.vexnum; i++)...{
for(int j = 0; j < g.vexnum; j++)...{
printf("%d ", g.arcs[i][j].adj);
}
printf(" ");
}
}
void createGragh(MGraph & g) ... {
printf("please input the type of graph: ");
scanf("%d", &g.kind);
switch(g.kind)...{
case DG:
createDG(g);
break;
case DN:
createDN(g);
break;
case UDG:
createUDG(g);
break;
case UDN:
createUDN(g);
printGraph(g);
break;
}
}
void dijkstra(MGraph g) ... {
int *dist = (int *)malloc(sizeof(int) * g.vexnum);
int *parent = (int *)malloc(sizeof(int) * g.vexnum);
int *final = (int *)malloc(sizeof(int) * g.vexnum);
int i, j, k, cost;
//init the arrays
for(i = 0; i < g.vexnum; i++)...{
dist[i] = g.arcs[0][i].adj;
parent[i] = 0;
final[i] = 0;
}
//join the start 0.
final[0] = 1;
for(i = 1; i < g.vexnum; i++)...{
//get the min of dist
cost = INFINITY;
k = -1;
for(j = 1; j < g.vexnum; j++)...{
if(dist[j] < cost && final[j] == 0)...{
cost = dist[j];
k = j;
}
}
if(k > 0)...{
//join the k node
final[k] = 1;
//update the dist
for(int t = 1; t < g.vexnum; t++)...{
if(final[t] == 0)...{
if(dist[t] > dist[k] + g.arcs[k][t].adj)...{
dist[t] = dist[k] + g.arcs[k][t].adj;
parent[t] = k;
}
}
}
}
}
//print the dist and parent array
printf("the shortest path from %c is as follows: ", g.vexs[0]);
for(i = 0; i < g.vexnum; i++)...{
printf("%c via %c's dist is %d ",
g.vexs[i], g.vexs[parent[i]], dist[i]);
}
}
void main() ... {
MGraph g;
createGragh(g);
dijkstra(g);
}
程序的执行结果如下:
please input the type of graph:
3
input the number of vertex:
6
input the name of vertex:
a
b
c
d
e
f
now constructing the matrix of graph...
0 10000 10 10000 30 100
10000 0 5 10000 10000 10000
10000 10000 0 50 10000 10000
10000 10000 10000 0 10000 10
10000 10000 10000 20 0 60
10000 10000 10000 10000 10000 0
the shortest path from a is as follows:
a via a ' s dist is 0
b via a ' s dist is 10000
c via a ' s dist is 10
d via e ' s dist is 50
e via a ' s dist is 30
f via d ' s dist is 60
Press any key to continue
3
input the number of vertex:
6
input the name of vertex:
a
b
c
d
e
f
now constructing the matrix of graph...
0 10000 10 10000 30 100
10000 0 5 10000 10000 10000
10000 10000 0 50 10000 10000
10000 10000 10000 0 10000 10
10000 10000 10000 20 0 60
10000 10000 10000 10000 10000 0
the shortest path from a is as follows:
a via a ' s dist is 0
b via a ' s dist is 10000
c via a ' s dist is 10
d via e ' s dist is 50
e via a ' s dist is 30
f via d ' s dist is 60
Press any key to continue
说明:Dijkstra算法的复杂度是O(n * n)。
(2)每一对顶点之间的最短路径
方法一:对每个顶点依次运行Dijkstra,复杂度O(n*n*n)。
方法二:floyd,复杂度O(n*n*n)。
头文件修改:
int
weight[][
3
]
=
...
{
...{0, 4, 11},
...{6, 0, 2},
...{3, INFINITY, 0}
} ;
...{0, 4, 11},
...{6, 0, 2},
...{3, INFINITY, 0}
} ;
void
floyd(MGraph g)
...
{
int dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int parent[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
//init the arrays
int i, j;
for(i = 0; i < g.vexnum; i++)...{
for(j = 0; j < g.vexnum; j++)...{
dist[i][j] = g.arcs[i][j].adj;
parent[i][j] = i;
}
}
//compute the shortest path
for(int k = 0; k < g.vexnum; k++)...{
for(i = 0; i < g.vexnum; i++)...{
for(j = 0; j < g.vexnum; j++)...{
if(i != j && i != k && j != k)...{
if(dist[i][j] > dist[i][k] + dist[k][j])...{
dist[i][j] = dist[i][k] + dist[k][j];
parent[i][j] = k;
}
}
}
}
}
//print the shortest path and parent
for(i = 0; i < g.vexnum; i++)...{
for(j = 0; j < g.vexnum; j++)...{
printf("%d(%c) ", dist[i][j], g.vexs[parent[i][j]]);
}
printf(" ");
}
}
void main() ... {
MGraph g;
createGragh(g);
dijkstra(g);
floyd(g);
}
int dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int parent[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
//init the arrays
int i, j;
for(i = 0; i < g.vexnum; i++)...{
for(j = 0; j < g.vexnum; j++)...{
dist[i][j] = g.arcs[i][j].adj;
parent[i][j] = i;
}
}
//compute the shortest path
for(int k = 0; k < g.vexnum; k++)...{
for(i = 0; i < g.vexnum; i++)...{
for(j = 0; j < g.vexnum; j++)...{
if(i != j && i != k && j != k)...{
if(dist[i][j] > dist[i][k] + dist[k][j])...{
dist[i][j] = dist[i][k] + dist[k][j];
parent[i][j] = k;
}
}
}
}
}
//print the shortest path and parent
for(i = 0; i < g.vexnum; i++)...{
for(j = 0; j < g.vexnum; j++)...{
printf("%d(%c) ", dist[i][j], g.vexs[parent[i][j]]);
}
printf(" ");
}
}
void main() ... {
MGraph g;
createGragh(g);
dijkstra(g);
floyd(g);
}
程序的运行结果如下:
please input the type of graph:
3
input the number of vertex:
3
input the name of vertex:
a
b
c
now constructing the matrix of graph...
0 4 11
6 0 2
3 10000 0
the shortest path from a is as follows:
a via a ' s dist is 0
b via a ' s dist is 4
c via b ' s dist is 6
0 (a) 4 (a) 6 (b)
5 (c) 0 (b) 2 (b)
3 (c) 7 (a) 0 (c)
Press any key to continue
3
input the number of vertex:
3
input the name of vertex:
a
b
c
now constructing the matrix of graph...
0 4 11
6 0 2
3 10000 0
the shortest path from a is as follows:
a via a ' s dist is 0
b via a ' s dist is 4
c via b ' s dist is 6
0 (a) 4 (a) 6 (b)
5 (c) 0 (b) 2 (b)
3 (c) 7 (a) 0 (c)
Press any key to continue