用邻接表存储的有向图,求其最短路径。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
#define MAX 20
typedef char Dtype;
typedef int mapmax[MAX][MAX];
int visited[MAX];//标记最优的那个集合
int D[MAX];//存储可达节点的距离
mapmax map;//存储路径
int count;//记录已经被标记的节点数
//-----------邻接表--------------
typedef char Diantype;
//弧的结构体
typedef struct ArcNode{
int adddain;//指向顶点位置的指针
int dis;//指向下一点的距离
struct ArcNode *nextarc;//指向下一条弧的指针
}ArcNode,*Arc;
//点的结构体
typedef struct VNode{
Diantype data;//顶点信息
ArcNode *firstarc;//指向第一条依附该点的弧的指针
}VNode, AdjList[MAX];
typedef struct{
AdjList toulist; //所有头节点的表
int dian,hu; //当前顶点数和弧数
}ALG;
int locate_dian(ALG H,Diantype a);
void Creat_ALG(ALG &H);
void init(ALG &H,int v)
{//初始化D数组和map数组,同时也也在后面不停的调用
visited[v]=1; count++;
if(H.toulist[v].firstarc)//如果这个节点有出度
{
ArcNode *p=H.toulist[v].firstarc;
while(p)
{
if(D[p->adddain]==0)//如果这个点所到达的点还未访问
{
int index=1;
D[p->adddain]=D[v]+p->dis;//D数组更新
map[p->adddain][1]=index++;map[p->adddain][p->adddain]=index++;//map路径更新
}
else
{
if(D[p->adddain]>D[v]+p->dis)//已经访问过了比较取最优路径
{
int index=map[v][1];
D[p->adddain]=D[v]+p->dis;
for(int i=1;i<=H.dian;i++)
{
index=index>map[v][i]?index:map[v][i];
map[p->adddain][i]=map[v][i];
}
map[p->adddain][p->adddain]=++index;
}
}
p=p->nextarc;
}
}
}
void Dj(ALG H)//每次被调用都会找到D数组中最小的然后调用init进行更新
{
int min=0;
for(int i=2;i<=H.dian;i++)
{
if(!visited[i] && D[i]>0)
{
if(min==0)
min=i;
else
{
if(D[min]>D[i])
min=i;
}
}
}
init(H,min);
}
int main()
{
ALG A;
Creat_ALG(A);
count=1;
memset(map,0,sizeof(map));
for(int i=0;i<MAX;i++)
{
visited[i]=0;
D[i]=0;
}
init(A,1); visited[1]=1;
//------------------以上为初始化---------------
while(count<A.dian)//最短路径的集合不满时,一直调用Dj函数。
Dj(A);
//---------------结果----------------
printf("原点到各点的最短距离\n");
for(int i=2;i<=A.dian;i++)
{
printf("%d ",D[i]);
}
printf("\n");
printf("输出路径\n");
for(int i=1;i<=A.dian;i++)
printf("%c ",A.toulist[i].data);
printf("\n");
for(int i=1;i<=A.dian;i++)
{
for(int j=1;j<=A.dian;j++)
{
printf("%d ",map[i][j]);
}
printf("\n");
}
return 0;
}
//---------------邻接表的建立----------------------
int locate_dian(ALG H,Diantype a)
{
for(int i=1;i<=H.dian;i++)
{
if(H.toulist[i].data==a)
return i;
}
return 0;
}
void Creat_ALG(ALG &H)
{//根据输入的有向图G的顶点数及边数,建立图G的邻接表
printf("请输入点数和弧数\n");
cin>>H.dian>>H.hu;
getchar();
printf("请输入节点信息\n");
for(int i=1;i<=H.dian;i++)
{
cin>>H.toulist[i].data;
H.toulist[i].firstarc=NULL;
}
getchar();
printf("请输入%d条弧\n",H.hu);
for(int k=1;k<=H.hu;k++)
{
int dis;
Diantype x,y;
int i,j;
ArcNode *p,*node;
scanf("%c%c%d",&x,&y,&dis);
getchar();
i=locate_dian(H,x);j=locate_dian(H,y);
//-----------i->j-----------
node=new ArcNode;
node->adddain=j; node->dis=dis;
node->nextarc=NULL;
p=H.toulist[i].firstarc;
if(!p)
H.toulist[i].firstarc=node;
else
{
while(p->nextarc)
p=p->nextarc;
p->nextarc=node;
}
}
}