D算法**-指定端到其他端的最短路径算法

数据结构与算法

D算法-指定端到其他端的最短路径算法

/*
D算法对有向图也适用
也可适用于端点有权的情况
D算法不适用于边的权有正有负的情况
2020-12-17 written by HL
*/
#include<bits/stdc++.h>
using namespace std;
#define MAX_VERTEX_NUM 100 //最大矩阵维度 
typedef struct MGRAPH
{
	int n;//图中顶点数目
	int e;//图中边的数目
	int vertex[MAX_VERTEX_NUM];
	int edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
} MGraph;

MGraph* CreateMGraph( )
{
	MGraph *G=new MGraph ;
	int i,j,k,w;
	printf("请输入顶点数目和边的数目:");
	scanf("%d%d",&G->n,&G->e);
	//初始化邻接矩阵
	for(i=0; i<G->n; i++)
		for(j=0; j<G->n; j++)
			G->edge[i][j]=INT_MAX;
	printf("请输入%d条边和对应的权值:",G->e);
	for(k=0; k<G->e; k++)
	{
		scanf("%d%d%d",&i,&j,&w);//输入边的信息 
		G->edge[i][j]=w;
		G->edge[j][i]=w;
	}
	return G; 
}

//输出从顶点 v出发的所有最短路径
void Dispath(MGraph*G,int dis[],int path[],int S[],int v)
{
	int i,j,k;
	int apath[MAX_VERTEX_NUM],d;//存放一条最短路径(逆向存放)及其顶点个数
	for(i=0; i<G->n; i++)
	{
		if(S[i]==1 && i!=v )
		{
			printf("顶点 %d 到顶点 %d 的路径长度:%d\t路径:",v,i,dis[i]);
			d=0;
			apath[d]=i;
			k=path[i];
			if(k==-1) printf("无路径\n");
			else
			{
				while(k!=v)
				{
					d++;
					apath[d]=k;
					k=path[k];
				}
				d++;
				apath[d]=v;//添加路径上的起点
				printf("%d",apath[d]);//先输出起点
				for(j=d-1; j>=0; j--)
				{
					printf(",%d",apath[j]);
				}
				printf("\n");
			}
		}
	}
}

void Dijkstra(MGraph *G,int v)
{
	int dis[MAX_VERTEX_NUM];//路径长度数组
	int path[MAX_VERTEX_NUM];
	int S[MAX_VERTEX_NUM];
	int mindis,i,j,u;
	for(i=0; i<G->n; i++)
	{
		dis[i]=G->edge[v][i];//初始化路径长度数组
		S[i]=0;
		if(G->edge[v][i]<INT_MAX) //路径长度
		{
			path[i]=v; //顶点v到顶点i有边
		}
		else
		{
			path[i]=-1;
		}
	}
	S[v]=1;
	path[v]=0;
	for(i=0; i<G->n; i++)
	{
		mindis=INT_MAX;
		for(int j=0; j<G->n; j++)
		{
			if(S[j]==0&&dis[j]<mindis)
			{
				u=j;
				mindis=dis[j];
			}
		}
		S[u]=1;//顶点u加入S中
		for(j=0; j<G->n; j++)
		{
			if(S[j]==0)
			{
				if(G->edge[u][j]<INT_MAX&&dis[u]+G->edge[u][j]<dis[j])
				{
					dis[j]=dis[u]+G->edge[u][j];
					path[j]=u;
				}
			}
		}
	}
	Dispath(G,dis,path,S,v);
}

int main()
{
    MGraph	*G=CreateMGraph();
    Dijkstra(G,0);
	system("pause"); 
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值