DS图应用--最短路径(迪杰特斯拉算法)

题目描述

给出一个图的邻接矩阵,再给出指定顶点v0,求顶点v0到其他顶点的最短路径

代码框架如下:

http://172.31.234.14/JudgeOnline/upload/pimg1225_1.jpg

http://172.31.234.14/JudgeOnline/upload/pimg1225_2.jpg

http://172.31.234.14/JudgeOnline/upload/pimg1225_3.jpg

输入

第一行输入t,表示有t个测试实例

第二行输入n,表示第1个图有n个结点

第三行起,每行输入邻接矩阵的一行,以此类推输入n

i个结点与其他结点如果相连则为1,无连接则为0,数据之间用空格隔开

第四行输入v0,表示求v0到其他顶点的最短路径距离

以此类推输入下一个示例

输出

每行输出v0到某个顶点的最短距离和最短路径

每行格式:v0编号-其他顶点编号----[最短路径],具体请参考示范数据

样例输入

1

5

0 5 0 7 15

0 0 5 0 0

0 0 0 0 1

0 0 2 0 0

0 0 0 0 0

0

样例输出

0-1-5----[0 1 ]

0-2-9----[0 3 2 ]

0-3-7----[0 3 ]

0-4-10----[0 3 2 4 ]

思路:

每次找到最短距离的顶点,然后依据这个顶点更新到其它顶点的最短距离

代码:

#include <iostream>
using namespace std;
#include <queue>
#include <string>
const int MaxLen =20;
const int MaxDist=9999;
class Map{
private:
    int Matrix[MaxLen][MaxLen];  //这种开数组是在栈上开的,最大开到2M,用new的话可以开更大空间
    int Vexnum;
public:
    void SetMatrix(int vnum,int mx[MaxLen][MaxLen]);
    void ShortestPath_DIJ(int v0);
};
void Map::SetMatrix(int vnum,int mx[MaxLen][MaxLen])
{
    int i,j;
    Vexnum = vnum;
    for(i=0;i<MaxLen;i++)
        for(j=0;j<MaxLen;j++)
            Matrix[i][j]=MaxDist;
    for(i=0;i<Vexnum;i++)
        for(j=0;j<Vexnum;j++)
            if(mx[i][j])
                Matrix[i][j]=mx[i][j];
}
void Map::ShortestPath_DIJ(int v0)
{
    int i,j,v,w,mmin;
    int *dist = new int[Vexnum];    //dist数组存顶点v0到其它顶点的最短距离
    bool *final = new bool[Vexnum];  //final数组用于标志dist数组的距离是否已经是最短距离
    int path[Vexnum][Vexnum];        //path二维数组每行存的是顶点v0到第i个顶点的最短路径
    int len[Vexnum];                //len数组存的是path最短路径的长度
    for(int i = 0; i < Vexnum; i++)        //final和dist初始化
    {
        final[i]=false;
        dist[i]=Matrix[v0][i];
    }
    for(int i=0;i<Vexnum;i++)        //path初始化
    {
        path[i][0]=v0;
        path[i][1]=i;
    }
    for(int i = 0;i<Vexnum;i++)       //len初始化
    {
        len[i]=2;
    }
    dist[v0]=0;                    //dist[v0]初始化为0,表示顶点到本身的距离
    final[v0]=true;                //顶点到本身的距离已经是最小,所以final置为true
    for(int i=0;i<Vexnum;i++)
    {
        mmin=MaxDist;
        for(int j=0;j<Vexnum;j++)   //每次取不是最短距离(即final!=true)的最小距离的那个顶点
        {
            if(!final[j] && mmin > dist[j])
            {
                mmin=dist[j];
                v=j;
            }
        }
        if(mmin==MaxDist)        //如果没取到,证明已经完成了,可以结束了
            break;
        else
        {
            final[v]=true;        //取到的话,要把对应顶点标志为已经最短距离
            for(int j=0;j<Vexnum;j++)       //再依据对应顶点的最短距离更新到其它顶点的最短距离,并更新路径path
            {
                if(!final[j] && Matrix[v][j]+mmin<dist[j])
                {
                    dist[j]=Matrix[v][j]+mmin;
                    for(int p=0;p<len[v];p++)
                    {
                        path[j][p]=path[v][p];
                    }
                    len[j]=len[v]+1;
                    path[j][len[j]-1]=j;
                }
            }
        }
    }
    for(int i=0;i<Vexnum;i++)        //输出
    {
        if(i!=v0 &&dist[i]!=MaxDist)
        {
            cout<<v0<<'-'<<i<<'-'<<dist[i]<<"----[";
            for(int j=0;j<len[i];j++)
            {
                cout<<path[i][j]<<' ';
            }
            cout<<']'<<endl;
        }
    }
    delete []dist;
    delete []final;
}
int main()
{
    int i,j,k,t;
    int vnum,v0;
    int mx[MaxLen][MaxLen];
    Map test;
    cin>>t;
    while(t--)
    {
        cin>>vnum;
        for(i=0;i<MaxLen;i++)
            for(j=0;j<MaxLen;j++)
                mx[i][j]=0;
        for(i=0;i<vnum;i++)        //以邻接矩阵方式读入图的信息
            for(j=0;j<vnum;j++)
                cin>>mx[i][j];
        cin>>v0;                    //读入开始顶点
        test.SetMatrix(vnum,mx);
        test.ShortestPath_DIJ(v0);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值