#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MAX_VERTEX_NUM 20
#define INFINITY INT_MAX
typedef struct MGraph
{
int vexnum, arcnum;
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
char verx[MAX_VERTEX_NUM];
}MGraph, *PMGraph;
PMGraph CreateMGraph()
{
char verx[3] = { 'a', 'b', 'c'};
int arcs[3][3] = {
{ 0, 4, 11 },
{ 6, 0, 2 },
{ 3, INFINITY, 0 }
};
PMGraph pmgraph = (PMGraph)malloc(sizeof(MGraph));
//printf("输入顶点数和边数:");
//scanf("%d %d", &pmgraph->vexnum, &pmgraph->arcnum);
//getchar();
pmgraph->arcnum = 5; //边数
pmgraph->vexnum = 3; //顶点数
for (int i = 0; i < pmgraph->vexnum; i++)
{
// printf("输入第 %d 个顶点名称:",i);
// scanf("%c", &pmgraph->verx[i]);
// getchar();
pmgraph->verx[i] = verx[i];
}
for (int i = 0; i < pmgraph->vexnum; i++)
{
for (int j = 0; j < pmgraph->vexnum; j++)
pmgraph->arcs[i][j] = arcs[i][j];
}
//printf("输入边的两个顶点及权值:\n");
//int u = 0, v = 0, w = 0;
//for (int i = 0; i < pmgraph->arcnum; i++)
//{
// printf("输入第 %d 条边:", i);
// scanf("%d %d %d", &u, &v, &w);
// pmgraph->arcs[u][v] = w;
// getchar();
//}
return pmgraph;
}
void PrintMGraph(PMGraph pmgraph)
{
for (int i = 0; i < pmgraph->vexnum; i++)
{
for (int j = 0; j < pmgraph->vexnum; j++)
{
if (pmgraph->arcs[i][j] != INFINITY)
{
printf("%d ", pmgraph->arcs[i][j]);
}
else
{
printf("∞ ");
}
}
printf("\n");
}
}
//单源最短路径
void Dijkstra(PMGraph pmgraph, int v0)
{
bool final[MAX_VERTEX_NUM]; //final[v]=true 表示以求得从v0到v的最短路径、
bool path[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //P[v][w]=true,则w是v0到v最短路径上的顶点
int D[MAX_VERTEX_NUM]; //D[v]表示顶点v0到v的最短路径长度
for (int v = 0; v < pmgraph->vexnum; v++)
{
final[v] = false;
D[v] = pmgraph->arcs[v0][v];
for (int w = 0; w < pmgraph->vexnum; w++)
{
path[v][w] = false;
}
if (D[v] < INFINITY)
{
path[v][v0] = true;
path[v][v] = true;
}
}
final[v0] = true;
D[v0] = 0;
int min = INFINITY, k = 0, tmp = 0;
for (int i = 1; i < pmgraph->vexnum; i++)
{
min = INFINITY;
for (int w = 0; w < pmgraph->vexnum; w++)
{
if (!final[w])
{
if (D[w] < min)
{
k = w;
min = D[w];
}
}
}
final[k] = true;
for (int w = 0; w < pmgraph->vexnum; w++)
{
tmp = pmgraph->arcs[k][w] == INFINITY ? INFINITY : (min + pmgraph->arcs[k][w]);
if (!final[w] && (tmp < D[w]))
{
D[w] = min + pmgraph->arcs[k][w];
path[w][k] = true;
path[w][w] = true;
}
}
}
for (int i = 0; i < pmgraph->vexnum; i++)
{
if (D[i] != INFINITY)
{
printf("%d: %d ----", i, D[i]);
for (int j = 0; j < pmgraph->vexnum; j++)
{
if (path[i][j])
printf("%d ", j);
}
printf("\n");
}
}
}
//任意两点之间最短路径
void Floyd(PMGraph pmgraph)
{
int D[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //D[v][w]表示顶点v,w之间的路径最短路径长度
bool P[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //P[v][w][u]表示顶点u为v,w最短路径上的顶点
for (int v = 0; v < pmgraph->vexnum; v++)
{
for (int w = 0; w < pmgraph->vexnum; w++)
{
D[v][w] = pmgraph->arcs[v][w];
for (int u = 0; u < pmgraph->vexnum; u++)
{
P[v][w][u] = false;
}
if (D[v][w] < INFINITY)
{
P[v][w][v] = true;
P[v][w][w] = true;
}
}
}
for (int u = 0; u < pmgraph->vexnum; u++)
{
for (int v = 0; v < pmgraph->vexnum; v++)
{
for (int w = 0; w < pmgraph->vexnum; w++)
{
int tmp = (D[v][u] < INFINITY && D[u][w] < INFINITY) ? D[v][u] + D[u][w] : INFINITY;
if (tmp < D[v][w])
{
D[v][w] = D[v][u] + D[u][w];
for (int i = 0; i < pmgraph->vexnum; i++)
P[v][w][u] = P[v][u][i] || P[u][w][i];
}
}
}
}
for (int v = 0; v < pmgraph->vexnum; v++)
{
for (int w = 0; w < pmgraph->vexnum; w++)
{
if (D[v][w] < INFINITY)
{
printf("%d--%d ; %d parh:", v, w, D[v][w]);
for (int u = 0; u < pmgraph->vexnum; u++)
{
if (P[v][w][u])
{
printf("%d ", u);
}
}
printf("\n");
}else
{
printf("%d--%d ; ∞\n", v, w);
}
}
}
}
int main()
{
PMGraph pmgraph = CreateMGraph();
PrintMGraph(pmgraph);
Dijkstra(pmgraph,0);
printf("\n");
Floyd(pmgraph);
return 0;
}
最短路径 (单源最短路径Dijkstra和任意两点最短路径Floyd) C实现
最新推荐文章于 2024-09-22 10:13:21 发布