第1关:求图(邻接矩阵存储)最短路径的狄克斯特拉算法
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#include<iostream>
using namespace std;
#include"MGraph.h"
void Dijkstra(MGraph g,int v); //求从v到其他顶点的最短路径
void DispAllPath(MGraph &g,int dist[],int path[],int S[],int v) ;//输出从顶点v出发的所有最短路径
void Dispdistpath(int dist[],int path[],int n); //输出dist数组和path数组
int main()
{
MGraph g;
int i,j,n;
CreateGraphF(g); /* 利用数据文件创建有向图*/
Display(g); /* 输出有向图*/
Dijkstra(g,0);
return 0;
}
void Dijkstra(MGraph g,int v)
{
//求从v到其他顶点的最短路径
/********** Begin **********/
int min,num,dist[MAX_VERTEX_NUM],path[MAX_VERTEX_NUM],s[MAX_VERTEX_NUM];
for(int i = 0; i < g.vexnum; i++)
{
dist[i] = g.arcs[v][i].adj;
if(dist[i]!=INFINITY)
{
path[i] = v;
}else{
path[i] = -1;
}
}
for(int i = 0; i < g.vexnum; i++) s[i] = 0;
{
s[v] = 1;
}
num = 1;
while(num<g.vexnum)
{
int mini = INFINITY,m;
for(int i = 0; i < g.vexnum; i++)
{
if(s[i]==0&&dist[i]<mini)
{
mini = dist[i];
m = i ;
}
}
s[m] = 1;
Dispdistpath(dist,path,g.vexnum);
for(int i = 0; i < g.vexnum; i++)
{
if(s[i] == 0 && (dist[i] > dist[m] + g.arcs[m][i].adj))
{
dist[i] = dist[m] + g.arcs[m][i].adj;
path[i] = m;
}
}
num++;
}
Dispdistpath(dist,path,g.vexnum);
DispAllPath(g,dist,path,s,v);
/********** End **********/
}
void DispAllPath(MGraph &g,int dist[],int path[],int S[],int v) //输出从顶点v出发的所有最短路径
{
int i,j,k,count=0;
int apath[MAX_VERTEX_NUM],d; //存放一条最短路径(逆向)及其顶点个数
for (i=0;i<g.vexnum;i++)
if (path[i]!=-1)
count++;
if (count==1) //path中只有一个不为-1时表示没有路径
{ printf("从指定的顶点到其他顶点都没有路径!!!\n");
return;
}
for (i=0;i<g.vexnum;i++) //循环输出从顶点v到i的路径
if (S[i]==1 && i!=v)
{
//printf("从%s到%s最短路径长度为:%s\t路径:",g.vexs [v],g.vexs[i],dist[i]);
cout<<"从"<<g.vexs [v]<<"到"<<g.vexs[i]<<"最短路径长度为:"<<dist[i]<<"\t";
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]); //先输出起点
cout<<g.vexs [ apath[d] ];
for (j=d-1;j>=0;j--) //再输出其他顶点
//printf("→%d",apath[j]);
cout<<"→"<<g.vexs [ apath[j] ];
printf("\n");
}
}
}
void Dispdistpath(int dist[],int path[],int n) //输出dist数组和path数组
{
int i;
printf("dist:\t");
for (i=0;i<n;i++)
if (dist[i]==INFINITY)
printf("%s\t","∞");
else
printf("%d\t",dist[i]);
printf("\n");
printf("path:\t");
for (i=0;i<n;i++)
printf("%d\t",path[i]);
printf("\n");
}
第2关:求图(邻接表存储)最短路径的狄克斯特拉算法
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
#include<iostream>
using namespace std;
#define INFINITY 4270000 // 用整型最大值代替∞
#include"ALGraph.h"
int GetWeight(ALGraph G,VertexType a,VertexType b );//获取权值
void Dijkstra(ALGraph g,int v); //求从v到其他顶点的最短路径
void DispAllPath(ALGraph &g,int dist[],int path[],int S[],int v) ;//输出从顶点v出发的所有最短路径
void Dispdistpath(int dist[],int path[],int n); //输出dist数组和path数组
int main()
{
ALGraph g;
int i,j,n;
CreateGraphF(g); /* 利用数据文件创建有向图*/
Display(g); /* 输出有向图*/
Dijkstra(g,0);
return 0;
}
void Dijkstra(ALGraph g,int v)
{
//求从v到其他顶点的最短路径
/********** Begin **********/
int min,num,dist[MAX_VERTEX_NUM],path[MAX_VERTEX_NUM],s[MAX_VERTEX_NUM];
int i;
for(i = 0; i < g.vexnum; i++)
{
dist[i] = GetWeight(g,g.vertices[v].data,g.vertices[i].data);
if(dist[i]!=INFINITY)
{
path[i] = v;
}
else
{
path[i] = -1;
}
}
for(i = 0; i < g.vexnum; i++)
{
s[i]=0;
s[v] = 1;
}
num = 1;
while(num<g.vexnum)
{
int mini = INFINITY,m;
for(i = 0; i < g.vexnum; i++)
{
if(s[i]==0&&dist[i]<mini)
{
mini = dist[i];
m = i ;
}
}
s[m] = 1;
Dispdistpath(dist,path,g.vexnum);
for(i = 0; i < g.vexnum; i++)
{
if(s[i] == 0 && (dist[i] > dist[m] + GetWeight(g,g.vertices[m].data,g.vertices[i].data)))
{
dist[i] = dist[m] + GetWeight(g,g.vertices[m].data,g.vertices[i].data);
path[i] = m;
}
}
num++;
}
Dispdistpath(dist,path,g.vexnum);
DispAllPath(g,dist,path,s,v);
/********** End **********/
}
void DispAllPath(ALGraph &g,int dist[],int path[],int S[],int v) //输出从顶点v出发的所有最短路径
{
int i,j,k,count=0;
int apath[MAX_VERTEX_NUM],d; //存放一条最短路径(逆向)及其顶点个数
for (i=0;i<g.vexnum;i++)
if (path[i]!=-1)
count++;
if (count==1) //path中只有一个不为-1时表示没有路径
{ printf("从指定的顶点到其他顶点都没有路径!!!\n");
return;
}
for (i=0;i<g.vexnum;i++) //循环输出从顶点v到i的路径
if (S[i]==1 && i!=v)
{
//printf("从%s到%s最短路径长度为:%s\t路径:",g.vexs [v],g.vexs[i],dist[i]);
cout<<"从"<<g.vertices [v].data <<"到"<<g.vertices [i].data <<"最短路径长度为:"<<dist[i]<<"\t";
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]); //先输出起点
cout<<g.vertices [ apath[d] ].data ;
for (j=d-1;j>=0;j--) //再输出其他顶点
//printf("→%d",apath[j]);
cout<<"→"<<g.vertices [ apath[j] ].data ;
printf("\n");
}
}
}
void Dispdistpath(int dist[],int path[],int n) //输出dist数组和path数组
{
int i;
printf("dist:\t");
for (i=0;i<n;i++)
if (dist[i]==INFINITY)
printf("%s\t","∞");
else
printf("%d\t",dist[i]);
printf("\n");
printf("path:\t");
for (i=0;i<n;i++)
printf("%d\t",path[i]);
printf("\n");
}
int GetWeight(ALGraph G,VertexType a,VertexType b )//获取权值
{ int pa,pb;
pa=LocateVex(G,a);
pb=LocateVex(G,b);
ArcNode* p;
p=G.vertices[pa].firstarc;
if(pa == pb)
return 0;
while(p!=NULL)
{ if( p->data.adjvex == pb)
return p->data.info;
else
p=p->nextarc;
}
return INFINITY;
}