#include "cstdio"
#include "queue"
#define MAX 20
#define INF 999
using namespace std;
int c[11][11];//邻接矩阵
int n; //图中结点个数
int dist[MAX]; //存储从源结点到各个结点的最短距离
int pre[MAX]; //pre[i]表示从源节点到结点i最短路径上的前驱
struct Node
{
int i; //结点编号
int length; //从源点到当前结点的路径长度
Node()
{
i = 0;
length = 0;
}
bool operator < (const Node &nod) const
{
return length > nod.length;
}
};
priority_queue<Node> pq; //从源点到当前结点的路径长度短的结点先出队列
void shortestPath(int v)
{
Node node, node1;
node.i = v; //结点编号
node.length = 0; //结点v为源节点,所以路径长为0
dist[v] = 0;
int j;
while(true) //搜索解空间树
{
//依次检查与当前扩展结点i相邻的所有结点
for(j=0; j<n; j++)
{ //如果顶点i到顶点j可达,且加入顶点i后使到达顶点j的路径变短
if(c[node.i][j] && dist[node.i]+c[node.i][j]<dist[j])
{
dist[j] = dist[node.i]+c[node.i][j]; //更新到从源结点到顶点j的距离
pre[j] = node.i; //顶点j的前驱顶点为顶点i
node1.i = j; //顶点j入优先队列
node1.length = dist[j];
pq.push(node1);
}
}
node = pq.top(); //取下一扩展结点,每次取具有最小当前路长的结点作为扩展结点
pq.pop();
if(pq.empty()) //如果优先队列为空,结束
break;
}
}
void init(int n1, int c1[11][11]) //初始化
{
n = n1;
int i, j;
for(i=0; i<n1; i++)
for(j=0; j<n1; j++)
c[i][j] = c1[i][j];
for(i=0; i<n1; i++)
dist[i] = INF;
}
//构造最优解
//v0为源点,vi为终点
void printPath(int v0, int vi, int pre[])
{
if(v0==vi)
return;
printPath(v0, pre[vi], pre);
printf("-->%d", vi);
}
int main()
{
int n1 = 11;
int c1[11][11]={
{0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 3, 0, 7, 2, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 9, 2, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2},
{0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
};
init(n1, c1);
printf("图的邻接矩阵为:\n");
int i, j;
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf("%d ", c[i][j]);
printf("\n");
}
int v0 = 0;
shortestPath(v0);
printf("顶点编号从0开始:\n");
for(i=0; i<n; i++)
{
if(i!=v0)
{
printf("源点%d到终点%d的最短路径长为:%d, ", v0, i, dist[i]);
printf("路径为:%d", v0);
printPath(v0, i, pre);
}
printf("\n");
}
return 0;
}
单源最短路径问题
最新推荐文章于 2019-12-03 20:05:21 发布