最短路径——Dijkstra算法
设计实现有向网,针对随机有向网实例和随机源点,用Dijkstra算法求解出单源点到其他各顶点的最短路径。给出求解过程的动态演示。可考虑实现不用存储结构上的实现。
如下图所示,若要建立一个这样的图,且源点为1时,则输入顺序为:
5 7
1 2 10
1 5 100
1 4 30
2 3 50
3 5 10
4 3 20
4 5 60
1
代码:
#include<iostream>
#include<queue>
#define INF 0x3f3f3f3f//用来表示正无穷
#define MAX 100 //最多可存放100个顶点
using namespace std;
typedef pair<int,int> P; //用于优先队列中距离与顶点的对应,其中first为距离,second为原点到达的点
bool visit[MAX]; //标记为已找出最短路径的点
int v,e,s; //v为点的个数,e为边的个数,s为源点
int graph[MAX][MAX]; //图的存储采用邻接矩阵
int dist[MAX]; //dist表示当前点距源点最短距离,最终为最短距离
int path[MAX];
void Init();//初始化
void Dijkstra(const int s);
void dfs(const int x);//将路径回溯出来
int main(void)
{
int from,to,cost;
while(1)
{
cout<<"请输入点、边的个数:"<<endl;
cin>>v>>e;
Init();
cout<<"请输入每条边的起点、终点以及相应的权值:"<<endl;
for(int i=1; i<=e; i++)
{
cin>>from>>to>>cost;
graph[from][to]=cost;
}
cout<<"请输入源点:"<<endl;
cin>>s;
Dijkstra(s);
cout<<s<<"点到每个点的最短距离为:"<<endl;
for(int i=1; i<=v; i++)
{
if(dist[i]==INF)
cout<<s<<"------>"<<i<<"不可到达"<<endl;
else
{
cout<<s<<"----->"<<i<<"的最短距离为:"<<dist[i]<<endl;
cout<<"改路径为:"<<endl;
if(i==s)
cout<<s<<"-->"<<s<<endl;
else
{
dfs(i);//输出路径
cout<<i<<endl;
}
}
}
}
return 0;
}
void Init()
{
for(int i=0; i<MAX; i++)
for(int j=0; j<MAX; j++)
graph[i][j]=INF;
for(int i=0; i<MAX; i++)
dist[i]=INF;
for(int i=0; i<MAX; i++)
visit[i]=false;
}
void Dijkstra(const int s)
{
dist[s]=0;
P p;
int vi;
priority_queue <P,vector<P>,greater<P> >que;//将pair<int,int>放入优先队列,并且规定按照pair.first的较小值建立优先权
que.push(P(0,s));
while(que.size())
{
p=que.top();
que.pop();
vi=p.second; //vi为当前源点编号
if(visit[vi])
continue;
visit[vi]=true;
for(int i=1; i<=v; i++)
{
if(!visit[i]&&dist[i]>dist[vi]+graph[vi][i]) //查找vi的相邻顶点
{
dist[i]=dist[vi]+graph[vi][i];
path[i]=vi;//i点的父亲节点为vi
que.push(P(dist[i],i));
}
}
}
}
void dfs(const int x)
{
if(x==s) //如果找到起点,就返回
return;
else
dfs(path[x]);//否则继续深搜
cout<<path[x]<<"-->";
}