/*
Theme:单源最短路经的迪杰斯特拉算法(Dijkstra)
Author:liu
date:2018/6/6
*/
/*
解题步骤:
1.将源点加入顶点集V,边集E为空
2.选择与顶点V中相连出去的图中最短的路径,加入E集合,新的顶点加入V集合
3.重复步骤2,知道所有顶点都在集合V中
*/
#include<iostream>
using namespace std;
#define MAXNUM 1000
class Graph
{
public:
void input();
void init();
void Dijkstra();
void output();
private:
int _n;//顶点数量
int _e;//边的数量
int _sor;//表示源点的标号
int** _dis;//邻接矩阵
int* _min_dis;//表示源点到该点的最短路径(目前)
int* _flag;//表示是否已经找完最短路径
int* _path;//记录达到顶点的前一个顶点
};
void Graph::input()
{
cin >> _n >> _e;
for (int i = 0; i<_n; i++)
{
_dis = new int*[_n];
}
for (int i = 0; i<_n; i++)
{
_dis[i] = new int[_n];
}
//初始化
for (int i = 0; i<_n; i++)
{
for (int j = i; j<_n; j++)
{
_dis[i][j] = _dis[j][i]=MAXNUM;
}
}
//输入距离
int a, b;
for (int i = 0; i<_e; i++)
{
cin >> a>>b;
cin >> _dis[b][a];
_dis[a][b] = _dis[b][a];
}
cin >> _sor;
}
void Graph::init()
{
_flag = new int[_n];
_path = new int[_n];
_min_dis = new int[_n];
for (int i = 0; i<_n; i++)
{
_flag[i] = 0;
_path[i] = i;
_min_dis[i] = MAXNUM;
}
_min_dis[_sor] = 0;
_flag[_sor] = 1;
_path[_sor] = _sor;
}
void Graph::Dijkstra()
{
init();
int pick = _sor;//新加入的点
for (int i = 1; i<_n; i++)
{
int next_pick = -1;//下一个加入的点
int min_now = MAXNUM;//此次的最小距离
for (int j = 0; j<_n; j++)
{
if (_flag[j] == 0)//没有选中的点
{
int temp = _dis[pick][j] + _min_dis[pick];//间接距离
if (temp<_min_dis[j])//间接距离和之前的距离相比
{
_min_dis[j] = temp;
_path[j] = pick;
}
if (_min_dis[j] < min_now)
{
next_pick = j;
min_now = _min_dis[j];
}
}
}
if (next_pick == -1)//没有源点可以达到的点了
break;
pick = next_pick;
_flag[pick] = 1;
}
}
void Graph::output()
{
for (int i = 0; i<_n; i++)
{
if (_flag[i])
{
int j = i;
while (_path[j] != j)
{
cout << j;
j = _path[j];
}
cout << j << '\n';
}
}
}
int main()
{
Graph g;
g.input();
g.Dijkstra();
g.output();
system("pause");
}
单源最短路经的迪杰斯特拉算法(Dijkstra)
最新推荐文章于 2023-06-04 21:25:29 发布