簡單圖論:遍歷所有最短路徑
阿新 • • 發佈:2019-01-07
今天遇到了兩道要求遍歷所有最短路徑的題,我一直做不對的原因竟是我把無向圖當成了有向圖,鬱悶的要死。
解決遍歷所有最短路徑,其實思路很簡單,首先通過經典演算法[各種演算法,Dijkstra,bellman,floyd]求出最短路徑的長度,然後就只能DFS來找尋起始點、終點一樣,長度為最短路徑長度的路徑即可,在DFS中可以使用Path[]陣列來儲存路徑。
DFS時注意要剪枝,路徑上已經走過的點不要重複走,可以用Visited[]來儲存。
這裡要注意的是,如果邊的權均為正,那麼DFS的效率還是挺高的,可以在大於最短路時直接剪掉
如果邊權存在負值,DFS就剪不了那麼多枝了...
基本的演算法如下:
初始時使用DFS(起點,0)即可,其中D表示的是終點,可以作為全域性變數,start表示起始點,整個圖都使用二維陣列來存的,不過轉成表演算法也差不多。
ansdis表示的是之前求出來的最短路,而shortnum統計最短路徑的條數。
void DFS(int start, int dis) { int i,j; if(dis>ansdist) return; //帶負權則不可剪枝 for(i=0;i<N;i++) { if(!Visited[i] && i!=start && Graph[start][i]!=Infinity) { if(dis + Graph[start][i] > ansdist) continue; //帶負權則不可剪枝 else if(i==D && dis+Graph[start][i]==ansdist) { Path[start]=i; shortnum++; //此時就可以把Path[]路徑列印或儲存 } else { Visited[start]=true; int temp=Path[start]; Path[start]=i; DFS(i,dis+Graph[start][i]); Visited[start]=false; Path[start]=temp; } } } }