单源最短路径问题

#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;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值