参考《大话数据结构》
题目描述
在带权有向图G中,给定一个源点v,求从v到G中的其余各顶点的最短路径问题,叫做单源点的最短路径问题。
在常用的单源点最短路径算法中,迪杰斯特拉算法是最为常用的一种,是一种按照路径长度递增的次序产生最短路径的算法。
可将迪杰斯特拉算法描述如下:
在本题中,读入一个有向图的带权邻接矩阵(即数组表示),建立有向图并按照以上描述中的算法求出源点至每一个其它顶点的最短路径长度。
输入格式
输入的第一行包含2个正整数n和s,表示图中共有n个顶点,且源点为s。其中n不超过50,s小于n。
以后的n行中每行有n个用空格隔开的整数。对于第i行的第j个整数,如果大于0,则表示第i个顶点有指向第j个顶点的有向边,且权值为对应的整数值;如果这个整数为0,则表示没有i指向j的有向边。当i和j相等的时候,保证对应的整数为0。
输出格式
只有一行,共有n-1个整数,表示源点至其它每一个顶点的最短路径长度。如果不存在从源点至相应顶点的路径,输出-1。
请注意行尾输出换行。
样例输入
4 10 3 0 10 0 4 02 0 0 00 0 1 0
样例输出
6 4 7
#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>#define MAXEDGE 50//题目要求顶点数最大为50#define MAXVEX 50#define INFINITY_ 65535typedef struct{//数据结构int vexs[MAXVEX];int arc[MAXVEX][MAXVEX];int numVertexes,numEdges;}MGraph;typedef int Patharc[MAXVEX];//用于存储最短路径下标的数组,值为前驱顶点的下标typedef int ShortPathTable[MAXVEX];//用于存储到个点最短路径的权值和,值表示v0到v的最短路径长度和void ShortestPath_Dijkstra(MGraph,int,Patharc*,ShortPathTable*);//算法void initial(MGraph*,int);//初始化void print(ShortPathTable*,int,int);//打印int main(){MGraph g;int n,s;scanf("%d %d",&n,&s);initial(&g,n);Patharc P;ShortPathTable D;ShortestPath_Dijkstra(g,s,&P,&D);print(&D,n,s);}void initial(MGraph* g,int n){g->numVertexes=n;for(int i=0;i<g->numVertexes;i++){for(int j=0;j<g->numVertexes;j++){scanf("%d",&(g->arc[i][j]));if(g->arc[i][j]==0){//题目要求若两个顶点没有边,则用0表示,这里用65535表示方便算法执行g->arc[i][j]=INFINITY_;}if(i==j)//顶点到自身权值依旧为0g->arc[i][j]=0;}}}void ShortestPath_Dijkstra(MGraph g,int s,Patharc*P,ShortPathTable*D){int final[g.numVertexes];int k;for(int i=0;i<g.numVertexes;i++){final[i]=0;(*P)[i]=-1;(*D)[i]=g.arc[s][i];}final[s]=1;(*D)[s]=0;for(int i=1;i<g.numVertexes;i++){int min=INFINITY_;for(int j=0;j<g.numVertexes;j++){if(!final[j]&&(*D)[j]<min){k=j;min=(*D)[j];}}final[k]=1;for(int j=0;j<g.numVertexes;j++){if(!final[j]&&(min+g.arc[k][j]<(*D)[j])){(*D)[j]=min+g.arc[k][j];(*P)[j]=k;}}}}void print(ShortPathTable*D,int n,int s){for(int i=0;i<n;i++){if(i!=s)if((*D)[i]==65535)printf("%d ",-1);else printf("%d ",(*D)[i]);}}