迪杰斯特拉算法求单源最短路径(c++)

#include<iostream>
#include<iomanip>
#include<string>
using namespace std;

#define INFINITY 65535                       /*无边时的权值*/
#define MAX_VERTEX_NUM  10                   /*最大顶点数*/

/*定义结构体*/
typedef struct MGraph
{
	string vexs[10];                           /*顶点信息*/
	int arcs[10][10];                          /*邻接矩阵*/
	int vexnum,arcnum;                         /*顶点数和边数*/
}MGraph;

int LocateVex(MGraph G,string u)               /*返回顶点u在图中的位置*/
{
	for(int i=0;i<G.vexnum;i++)
		if(G.vexs[i]==u)
			return i;                        /*如果存在则返回位置,否则返回-1*/
	return -1;                        
}

void CreateDN(MGraph &G)                     /*构造有向网*/
{
	string v1,v2;
	int w;                                   /*权值*/
	int i,j,k;
	cout<<"请输入顶点数和边数:";
	cin>>G.vexnum>>G.arcnum;

	cout<<"请输入顶点:";
	for(i=0;i<G.vexnum;i++)
		cin>>G.vexs[i];

	for(i=0;i<G.vexnum;i++)                /*每个边的权值初始化为无穷大*/
	{                 
		for(j=0;j<G.vexnum;j++)
		{
			G.arcs[i][j]=INFINITY;
		}
	}

	cout<<"请输入边和权值:"<<endl;
	for(k=0;k<G.arcnum;k++)
	{
		cin>>v1>>v2>>w;                     /*输入顶点v1和v2以及它们之间的权值*/
		i=LocateVex(G,v1);
		j=LocateVex(G,v2);
		G.arcs[i][j]=w;                     /*根据输入的顶点找到该顶点在图中的位置并给这个边赋值*/
	}
}


/*迪杰斯特拉算法求有向网G的v0顶点到其余顶点v的最短路径p[v]及带权长度D[v]
p[][]=-1表示没有路径,p[v][i]存的是从v0到v当前求得的最短路径经过的第i+1个顶点(这是打印最短路径的关键),
则v0到v的最短路径即为p[v][0]到p[v][j]直到p[v][j]=-1,路径打印完毕。
final[v]为true当且仅当v属于s,即已经求得从v0到v的最短路径。
*/

void ShortestPath_DIJ(MGraph G,int v0,int p[][MAX_VERTEX_NUM],int D[])
{
	int v,w,i,j,min;
	bool final[10];

	for(v=0;v<G.vexnum;v++)
	{
		final[v]=false;                      /*设初值*/
		D[v]=G.arcs[v0][v];                  /*D[]存放v0到v的最短距离,初值为v0到v的直接距离*/
        for(w=0;w<G.vexnum;w++)
			p[v][w]=-1;                      /*设p[][]初值为-1,即没有路径*/
        if(D[v]<INFINITY)                    /*v0到v有直接路径*/
		{
			p[v][0]=v0;                      /*v0到v最短路径经过的第一个顶点*/
			p[v][1]=v;                       /*v0到v最短路径经过的第二个顶点*/
		}
	}

   	D[v0]=0;                                /*v0到v0的距离为0*/
	final[v0]=true;                         /*v0顶点并入s集*/

	for(i=1;i<G.vexnum;i++)                 /*其余G.vexnum-1个顶点*/
	{
		/*开始主循环,每次求得v0到某个顶点v的最短路径,并将v并入s集,然后跟新p和D*/
		min=INFINITY;
		for(w=0;w<G.vexnum;w++)             /*对所有顶点检查*/
			if(!final[w]&&D[w]<min)         /*在s集之外(即final[]=false)的顶点中找离v0最近的顶点,将其赋给v,距离赋给min*/
			{
				v=w;
				min=D[w];
			}	
			final[v]=true;                  /*v并入s集*/

            for(w=0;w<G.vexnum;w++)         /*根据新并入的顶点,跟新不在s集的顶点到v0的距离和路径数组*/
			{
				if(!final[w]&&min<INFINITY&&G.arcs[v][w]<INFINITY&&(min+G.arcs[v][w])<D[w])
				{
					/*w不属于s集v0->v->w的距离<目前v0->w的距离*/
					D[w]=min+G.arcs[v][w];    /*跟新D[w]*/
					for(j=0;j<G.vexnum;j++)    /*修改p[w],v0到w经过的顶点包括v0到v经过的所有顶点再加上顶点w*/
					{
						p[w][j]=p[v][j];
						if(p[w][j]==-1)        /*在p[w][]第一个等于-1的地方加上顶点w*/
						{
							p[w][j]=w;
							break;
						}
					}
				}
			}
	}

}


void main()
{
	int i,j;
	MGraph g;
	CreateDN(g);
	int p[MAX_VERTEX_NUM][MAX_VERTEX_NUM];             /*最短路径数组*/
	int D[MAX_VERTEX_NUM];                             /*最短距离数组*/
	ShortestPath_DIJ(g,0,p,D);

	cout<<"最短路径数组p[i][j]如下:"<<endl;
	for(i=0;i<g.vexnum;i++)
	{
		for(j=0;j<g.vexnum;j++)
			cout<<setw(3)<<p[i][j]<<" ";
		cout<<endl;
	}

	cout<<g.vexs[0]<<"到各顶点的最短路径及长度为:"<<endl;
	for(i=0;i<g.vexnum;i++)
	{
		if(i!=0&&D[i]!=INFINITY)
		{
			cout<<g.vexs[0]<<"-"<<g.vexs[i]<<"的最短路径长度为:"<<D[i];
			cout<<"最短路径为:";
			for(j=0;j<g.vexnum;j++)
			{
				if(p[i][j]>-1)
					cout<<g.vexs[p[i][j]]<<" ";
			}
			cout<<endl;
		}
		else if(D[i]==INFINITY)
			cout<<g.vexs[0]<<"-"<<g.vexs[i]<<":"<<"不可达"<<endl;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值