最短路徑——Dijkstra演算法
阿新 • • 發佈:2021-01-14
Dijkstra演算法
求某一個到任意點的最短路徑
Dijkstra演算法算是貪心思想實現的,首先把起點到所有點的距離存下來找個最短的,然後鬆弛一次再找出最短的,所謂的鬆弛操作就是,遍歷一遍看通過剛剛找到的距離最短的點作為中轉站會不會更近,如果更近了就更新距離,這樣把所有的點找遍之後就存下了起點到其他所有點的最短距離。
鄰接矩陣:
0 | 1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|---|
0 | 0 | 4 | 6 | 6 | INF | INF | INF |
1 | INF | 0 | 1 | INF | 7 | INF | INF |
2 | INF | INF | 0 | INF | 6 | 4 | INF |
3 | INF | INF | 2 | 0 | INF | 5 | INF |
4 | INF | INF | INF | INF | 0 | INF | 6 |
5 | INF | INF | INF | INF | 1 | 0 | 8 |
6 | INF | INF | INF | INF | INF | INF | 0 |
C++程式碼實現:
#include <bits/stdc++.h>
using namespace std;
///全域性變數區域
const int MAX = 32767;
const int maxn = 15;
int dist[maxn];//儲存i->j的當前最短路徑長度
int path[maxn];//只儲存i->j當前最短路徑中的前一個頂點的編號
bool visited[maxn];
int v[maxn][maxn];
int n; //實際結點數
///
void Dijkstra(int node)
{
memset(visited,0,sizeof(visited) ); //全部賦值為false 全部未訪問
for(int i=0;i<n;i++) //初始化dist陣列和path陣列
{
dist[i] = v[node][i];
path[i] = node;
}
visited[node] = true; //訪問node節點
for(int i=1;i<n;i++) //剩下n-1個節點
{
int minE=MAX; //minE賦一個較大值
int flag; //最短路的標號
for(int j=0;j<n;j++)
{
if(visited[j] == false && dist[j] < minE) //在dist[]中找最近的節點
{
minE = dist[j];
flag = j;
}
}
visited[flag] = true; //訪問最近的節點
for(int j=0;j<n;j++) //更新兩個陣列
{
if(dist[flag] + v[flag][j] < dist[j]) //如果通過flag節點到某一個節點j更近 就從flag節點通過 更新dist[] 和 path[]
{
dist[j] = dist[flag] + v[flag][j];
path[j] = flag;
}
}
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>v[i][j];
Dijkstra(0);
cout<<"dist: [";
for(int i=0;i<n;i++)
cout<<dist[i]<<" ";
cout<<"]"<<endl;
cout<<"path: [";
for(int i=0;i<n;i++)
cout<<path[i]+1<<" ";
cout<<"]"<<endl;
}
input.txt
7
0 4 6 6 32767 32767 32767
32767 0 1 32767 7 32767 32767
32767 32767 0 32767 6 4 32767
32767 32767 2 0 32767 5 32767
32767 32767 32767 32767 0 32767 6
32767 32767 32767 32767 1 0 8
32767 32767 32767 32767 32767 0
output.txt
dist: [0 4 5 6 10 9 16 ]
path: [0 0 1 0 5 2 4 ]