上学期学完数据结构 这学期才开始写dijkstra 真是水的可以
问题描述: 给定一个带权有向图G与源点v,求从v到G中其他顶点的最短路径(权值必须大于0)
算法描述:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用T表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到T中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,T中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
源代码:
1 #include<stdio.h> 2 #define MAX 100000 3 int arcs[10][10];//邻接矩阵 4 int D[10];//保存最短路径长度 5 int p[10][10];//路径,每一行代表v0到达该点的路径,若为1,则路径上有该点 6 int final[10];//若final[i] = 1则说明 顶点vi已在集合S中 7 int n ;//顶点个数 8 int v0 = 0;//源点 9 int v,w; 10 void Shortestpath_Dijkstra() 11 { 12 for(v=0;v<n;v++)//初始化 13 { 14 final[v]=0; 15 D[v]=arcs[v0][v]; 16 for(w=0;w<n;w++) p[v][w]=0; 17 if(D[v]<MAX) 18 { 19 p[v][v0]=1;//v0在路径中 20 p[v][v]=1;// v在路径中 21 }// don't know 22 } 23 D[v0]=0;final[v0]=1; 24 for(int i=1;i<n;i++) //主循环 25 { 26 int min=MAX; 27 for(int w=0;w<n;w++) // 找到本次最小距离的点 28 { 29 if(final[w]==0) 30 { 31 if(D[w]<min) 32 { 33 v=w; 34 min=D[w]; 35 } 36 } 37 } 38 final[v]=1; 39 for(int w=0;w<n;w++) //更新距离 40 { 41 if(final[w]==0&&(min+arcs[v][w]<D[w])) 42 { 43 D[w]=min+arcs[v][w]; 44 for(int j=0;j<n;j++) 45 { 46 p[w][j]=p[v][j]; //p[w]=p[v] 要将w并入路径中,则经过v的路径中的所有点都经过w 47 } 48 p[w][w]=1; //w自己也在路径中 49 } 50 } 51 } 52 } 53 int main() 54 { 55 FILE* fp=fopen("dijkstra_data.txt","r"); 56 if(fp==NULL) 57 { 58 printf("open file error\n"); 59 return 0; 60 } 61 scanf("%d",&n); 62 for(int i=0;i<n;i++) 63 { 64 for(int j=0;j<n;j++) 65 { 66 fscanf(fp,"%d",&arcs[i][j]); 67 } 68 } 69 Shortestpath_Dijkstra(); 70 for(int i=0;i<n;i++) 71 { 72 printf("%d--",D[i]); 73 for(int j=0;j<n;j++) 74 { 75 if(p[i][j]==1) printf("%d",j); 76 } 77 printf("\n"); 78 } 79 if(fclose(fp)!=0) printf("close file error\n"); 80 }
时间复杂度o(n²)