Dijkstra算法

基本思想:
1.设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,
2.对vi∈V - S,假设从源点v到vi的有向边为最短路径(从v到其余顶点的最短路径的初值)。
3.以后每求得一条最短路径v, …, vk,就将vk加入集合S中,并将路径v, …, vk, vi与原来的假设相比较,取路径长度较小者为最短路径。

Dijkstra基本思想
辅助数组
1.dist[MaxSize]数组,是用来保存从固定一个顶点向其他所有的点连通路的最小边权。
2.path[MaxSize]数组,存储路径,表示该点的下一个顶点位置。
3.visited[MaxSize]数组,存储该点是否已经被访问过。

Dijkstra算法实现代码
1.第一步,为dist赋初值,为第一个顶点与之相连接边的权值,不连通则赋值无穷大。访问数组全部赋值0,都没有被访问。path数组初值-1 。
2.循环n-1次,找到n-1条路径。每次循环的内容是:找到dist中最短的那条边,然后记录位置,使这个位置成为这一次循环确定的最短通路。
3.然后把这条边加入到已经确定的通路集合里,遍历其他所有的顶点,进行松弛操作,若新点与之连接比之前连接的顶点短,则更新dist数组。
4.最后的输出利用的栈,因为想要使从开头走向结尾,如果想要反向,则去掉栈。

#include
#include
using namespace std;
const int MaxSize = 20;
const int INF = 9999;
int dis[MaxSize];
int visited[MaxSize];
int path[MaxSize];
class MGraph
{
int arcNum;
int vertexNum;
int arc[MaxSize][MaxSize];
public:
MGraph(int n, int e)
{
arcNum = e;
vertexNum = n;
for (int i = 0; i < vertexNum; ++i)
{
for (int j = 0; j < vertexNum; ++j)
{
if (i == j)
arc[i][j] = 0;
else
arc[i][j] = INF;
}
}
for (int i = 0; i < arcNum; ++i)
{
int a, b, v;
cin >> a >> b >> v;
arc[a][b] = v;
}
}
void Dijkstra(int v)
{
for (int i = 0; i < vertexNum; ++i)
{
dis[i] = arc[v][i];
visited[i] = 0;
path[i] = -1;
}
visited[v] = 1;
for (int i = 0; i < vertexNum; ++i)
{
int min = INF;
int k = 0;
for (int j = 0; j < vertexNum; ++j)
{
if (min > dis[j] && visited[j] == 0)
{
min = dis[j];
k = j;
}
}
visited[k] = 1;
for (int j = 0; j < vertexNum; ++j)
{
if (visited[j] == 0 && dis[j] > dis[k] + arc[k][j])
{
dis[j] = dis[k] + arc[k][j];
path[j] = k;
}
}
}
}
};
int main()
{
int x, y;
cin >> x >> y;
int s, e;
cin >> s >> e;
MGraph G(x, y);
G.Dijkstra(s);
if (dis[e] == INF)
cout << “no answer” << endl;
else
{
cout << dis[e] << endl;
cout << “v” << s << " ";
int p = e;
stackst;
while (path[p] != -1)
{
st.push(path[p]);
p = path[p];
}
while (!st.empty())
{
cout << “v” << st.top() << " ";
st.pop();
}
cout << “v” << e;
}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值