📅  最后修改于: 2023-12-03 14:40:43.853000             🧑  作者: Mango
Dijkstra算法用于解决带权有向图的最短路径问题,例如网络路由等。
该算法利用贪心思想,每次从起点选择当前最短路径可以到达的未标记节点,直到到达终点。
#include<iostream> //输入输出头文件
#include<cstring> //字符串头文件
#include<algorithm> //STL头文件
using namespace std;
const int MAX = 1005; //最大节点数
const int INF = 0x3f3f3f3f; //无限大
//边类
class Edge{
private:
int v, w; //边的终点和权值
public:
Edge(){} //构造函数
Edge(int v, int w):v(v),w(w){}
int getV(){return v;} //返回边的终点
int getW(){return w;} //返回边的权值
};
//最短路径类
class ShortestPath{
private:
int n, s; //节点数和起点
int dis[MAX]; //距离数组
int pre[MAX]; //前驱数组
bool vis[MAX]; //标记数组
vector<Edge> G[MAX]; //邻接表表示图
public:
ShortestPath(int n, int s):n(n),s(s){}
void addEdge(int u, int v, int w){ //添加边
G[u].push_back(Edge(v,w));
}
void dijkstra(){ //Dijkstra算法
memset(vis,false,sizeof(vis));
memset(pre,-1,sizeof(pre));
fill(dis,dis+n,INF);
dis[s] = 0;
for(int i=0; i<n; i++){
int u = -1; //找到距离最小的节点
for(int j=0; j<n; j++){
if(!vis[j] && (u==-1 || dis[j]<dis[u]))
u = j;
}
vis[u] = true;
for(int j=0; j<G[u].size(); j++){ //更新距离
int v = G[u][j].getV();
if(!vis[v] && dis[u]+G[u][j].getW()<dis[v]){
dis[v] = dis[u]+G[u][j].getW();
pre[v] = u;
}
}
}
}
void printPath(int u){ //打印路径
if(pre[u]!=-1) printPath(pre[u]);
printf("%d ",u);
}
void printDis(int u){ //打印距离
printf("%d",dis[u]);
}
};
int main(){
int n = 5, s = 0; //节点数和起点
ShortestPath sp(n,s); //创建最短路径类
sp.addEdge(0,1,2); sp.addEdge(0,2,4);
sp.addEdge(1,2,1); sp.addEdge(1,3,7); sp.addEdge(2,3,3); sp.addEdge(2,4,5);
sp.addEdge(3,4,1);
sp.dijkstra(); //求最短路径
sp.printPath(4); //打印路径
printf("\n");
sp.printDis(4); //打印距离
printf("\n");
return 0;
}
```C++
#include<iostream> //输入输出头文件
#include<cstring> //字符串头文件
#include<algorithm> //STL头文件
using namespace std;
const int MAX = 1005; //最大节点数
const int INF = 0x3f3f3f3f; //无限大
//边类
class Edge{
private:
int v, w; //边的终点和权值
public:
Edge(){} //构造函数
Edge(int v, int w):v(v),w(w){}
int getV(){return v;} //返回边的终点
int getW(){return w;} //返回边的权值
};
//最短路径类
class ShortestPath{
private:
int n, s; //节点数和起点
int dis[MAX]; //距离数组
int pre[MAX]; //前驱数组
bool vis[MAX]; //标记数组
vector<Edge> G[MAX]; //邻接表表示图
public:
ShortestPath(int n, int s):n(n),s(s){}
void addEdge(int u, int v, int w){ //添加边
G[u].push_back(Edge(v,w));
}
void dijkstra(){ //Dijkstra算法
memset(vis,false,sizeof(vis));
memset(pre,-1,sizeof(pre));
fill(dis,dis+n,INF);
dis[s] = 0;
for(int i=0; i<n; i++){
int u = -1; //找到距离最小的节点
for(int j=0; j<n; j++){
if(!vis[j] && (u==-1 || dis[j]<dis[u]))
u = j;
}
vis[u] = true;
for(int j=0; j<G[u].size(); j++){ //更新距离
int v = G[u][j].getV();
if(!vis[v] && dis[u]+G[u][j].getW()<dis[v]){
dis[v] = dis[u]+G[u][j].getW();
pre[v] = u;
}
}
}
}
void printPath(int u){ //打印路径
if(pre[u]!=-1) printPath(pre[u]);
printf("%d ",u);
}
void printDis(int u){ //打印距离
printf("%d",dis[u]);
}
};
int main(){
int n = 5, s = 0; //节点数和起点
ShortestPath sp(n,s); //创建最短路径类
sp.addEdge(0,1,2); sp.addEdge(0,2,4);
sp.addEdge(1,2,1); sp.addEdge(1,3,7); sp.addEdge(2,3,3); sp.addEdge(2,4,5);
sp.addEdge(3,4,1);
sp.dijkstra(); //求最短路径
sp.printPath(4); //打印路径
printf("\n");
sp.printDis(4); //打印距离
printf("\n");
return 0;
}