//最短路径-一个顶点到各点(迪杰斯特拉算法)
#include<stdio.h>
#define MAX 30
#define TRUE 1
#define FALSE 0
#define INFINITY 1000
typedef enum{DG,DN,UDG,UDN} Graphkind;
typedef struct arccell //定义表示弧的邻接矩阵
{
int adj;
int *info; //弧的相关信息
}arccell,adjmatrix[MAX][MAX];
typedef struct //定义一个图类型
{
int vexs[MAX]; //存放顶点的值
adjmatrix arcs; //存放边
int vexnum,arcnum; //图中顶点和边的个数
Graphkind kind; //图的种类
}mgraph;
/
typedef int pathmatrix[MAX][MAX];
typedef int shortpathtable[MAX];
///
//找出值为v的顶点在图的存储数组中的索引
int locatevex(mgraph G,int v)
{
for(int i=0;i<G.vexnum;++i)
if(G.vexs[i]==v)return i;
}
int createDN(mgraph &G) //构造有向网
{
int i,j,k;
int v1,v2,w;
printf("输入有向网的顶点个数和边的个数:/n");
scanf("%d%d",&G.vexnum,&G.arcnum);
printf("输入有向网的各顶点的值:/n");
for(i=0;i<G.vexnum;++i)
scanf("%d",&G.vexs[i]);
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=0;}
for(k=0;k<G.arcnum;++k)
{
printf("输入无向网边的两个关联顶点和边的权值:/n");
scanf("%d%d%d",&v1,&v2,&w);
i=locatevex(G,v1);
j=locatevex(G,v2);
G.arcs[i][j].adj=w;
}
return 1;
}
//求从v0到各个顶点的最短路径,用P返回路径,用D返回各路径的总权值
void shortpath_DJIK(mgraph G,int k,pathmatrix &P,shortpathtable &D)
{
int v,v0,w,i,j;
int final[MAX]; //用此数组表示某个顶点是否已经并入s集合,其中final[i]表示G中索引为i的顶点
v0=locatevex(G,k);//求数值为k的顶点在G中的索引
for(v=0;v<G.vexnum;++v)
{
final[v]=FALSE; //初始化s集合为空集
D[v]=G.arcs[v0][v].adj; //初始化D[i]为v0到i顶点的权
for(w=0;w<G.vexnum;++w)
P[v][w]=FALSE; //初始化路径
if(D[v]<INFINITY)
{P[v][v0]=TRUE;P[v][v]=TRUE;}
}
D[v0]=0;
final[v0]=TRUE; //初始化,v0顶点属于s集
//开始主循环
for(i=1;i<G.vexnum;++i)
{
int min;
min=INFINITY; //给min赋一个较大的值以便比较
for(w=0;w<G.vexnum;++w)
if(!final[w])
if(D[w]<min){v=w;min=D[w];}//求出距离v0顶点最近的顶点在G中的索引w,并把v0到它的权赋给D[w]
final[v]=TRUE; //将v顶点并入s集合
for(j=0;j<G.vexnum;++j)
if(!final[j]&&(min+G.arcs[v][j].adj<D[j]))
{
D[j]=min+G.arcs[v][j].adj;
for(int h=0;h<G.vexnum;++h)P[j][h]=P[v][h];
P[j][j]=TRUE;
}
}
}
//输出起点到各个顶点的最小长度和经过的顶点的函数
void print_DJIK(mgraph G,pathmatrix P,shortpathtable D)
{
int i,j;
for(i=0;i<G.vexnum;++i)
{
if(D[i]==1000)printf("/n从起点到顶点%d无最短路径/n",G.vexs[i]);
else
{
printf("/n从起点到顶点%d的最短路径长度为:%d/n经过的顶点有:/n",G.vexs[i],D[i]);
for(j=0;j<G.vexnum;++j)
if(P[i][j]!=0)printf("%d ",G.vexs[j]);
}
}
}
void main()
{
pathmatrix p;
shortpathtable d;
mgraph g1;
createDN(g1);
shortpath_DJIK(g1,0,p,d);
print_DJIK(g1,p,d);
}