求有向圖最短路徑條數
阿新 • • 發佈:2019-01-02
(2)Dijkstra演算法
使用兩次Dij演算法,第一次計算最短路徑,第二次計算路徑條數。
int cost[MAX][MAX],dist[MAX],dist2[MAX],num[MAX][MAX]={{0,0}},ci[MAX]={0}; //dist2[]是在第二次寫dijikstra時,記錄最短路徑長//存在重邊的情況,num[][]記錄重邊的條數 //c[i]記錄從點v到到i的最短路徑條數 //第一次應用dijikstra,計算最短路徑,儲存在dist[]中 void shortestpath(int n,int v) { int i,j,k,s[MAX],min; for(i=1;i<=n;i++) { s[i]=0; dist[i]=cost[v][i]; } s[v]=1; for(i=1;i<=n;i++) { k=0; min=MAXN; for(j=1;j<=n;j++) { if(s[j]==0) { if(dist[j]<min&&dist[j]!=0) { min=dist[j]; k=j; } } } if(k==0) { break; } s[k]=1; for(j=1;j<=n;j++) { if(s[j]==0&&cost[k][j]<MAXN) { if(cost[k][j]+dist[k]<dist[j]) { dist[j]=cost[k][j]+dist[k]; } } } } } //第二次應用dijikstra,計算最短路徑條數 void dij(int n,int v) { int i,s[MAX],j,k,min; for(i=1;i<=n;i++) { s[i]=0; dist2[i]=cost[v][i]; if(dist2[i]==dist[i]) //如果i到v之間存在直接通路且長度就是最短路徑,c[i]=num[v][i] { ci[i]=num[v][i]; } } s[v]=1; for(i=1;i<=n;i++) { k=0; min=MAXN; for(j=1;j<=n;j++) { if(s[j]==0&&dist2[j]<min&&dist2[j]!=0) { min=dist2[j]; k=j; } } if(k==0) { break; } s[k]=1; for(j=1;j<=n;j++) { if(dist2[k]+cost[k][j]<dist2[j]) { dist2[j]=dist2[k]+cost[k][j]; } if(dist2[k]+cost[k][j]==dist[j]) //重置c[i],如果以k為中間點,v到j的距離剛好是最短路徑長度,那麼c[i]需要重置 { ci[j]=ci[k]*num[k][j]+ci[j]; } } } }