上學期學完數據結構 這學期纔開始寫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中的頂點爲中間頂點的當前最短路徑長度。spa
源代碼:code
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²)blog