数据结构与算法
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;
}