头文件 Graph.h:
#include<iostream>
#define MaxVertexNum 30
#define INFINITY 30000
#define VertexType char
#define EdgeType int
using namespace std;
typedef struct
{
VertexType vertexs[MaxVertexNum];//顶点表
EdgeType arcs[MaxVertexNum][MaxVertexNum];//边表(1或权值)
int vertexNum,edgeNum;//顶点数和边数
}MGraph;//邻接矩阵
MGraph CreatGraph()
{
MGraph G;
int i,j,k,w;
cin>>G.vertexNum>>G.edgeNum;
for(i=0;i<G.vertexNum;i++)
cin>>G.vertexs[i];
for(i=0;i<G.vertexNum;i++)
for(j=0;j<G.vertexNum;j++)
{
if(i==j)
G.arcs[i][j]=0;//初始化邻接矩阵
else
G.arcs[i][j]=INFINITY;//相当于无穷大的权值
}
/*无权值时(初始化时也要改)
for(k=0;k<G->vertexNum;k++)
{
cin>>i>>j;
G->arcs[i][j]=1;//若加入G->arcs[j][i]=1;为无向图
}*/
for(k=0;k<G.edgeNum;k++)
{
cin>>i>>j>>w;
G.arcs[i][j]=G.arcs[j][i]=w;//无向图
}
return G;
}
void Visit(int v)
{
}
//对邻接矩阵 深度优先搜索DFS
int visited[MaxVertexNum];
void DFS(MGraph *G,int v)
{
int j;
Visit(v);//访问第v个结点
visited[v]=1;//标志已访问
for(j=0;j<G->vertexNum;j++)
{
if(G->arcs[v][j]<INFINITY&&!visited[j])
DFS(G,j);
}
}
void DFStravese(MGraph *G)
{
int v;
for(v=0;v<G->vertexNum;v++)//初始化标志向量
visited[v]=0;
for(v=0;v<G->vertexNum;v++)//将所有未被访问的结点设为起点,进行深度搜索
if(!visited[v])
DFS(G,v);
}
/*
//对邻接矩阵 广度优先搜索
int visited[MaxVertexNum];
void BFStravese(MGraph *G)
{
int v;
for(v=0;v<G->vertexNum;v++)//初始化标志向量
visited[v]=0;
for(v=0;v<G->vertexNum;v++)//将所有未被访问的结点设为起点,进行广度搜索
if(!visited[v])
BFS(G,v);
}
void BFS(MGraph *G,int v)
{
int i,j;
PSeqQueue Q;//用到队列
Q=Init_SeqQueue();
Visit(v);
visited[v]=1;
In_SeqQueue(Q,v);
while(!Empty_SeqQueue(Q))
{
Out_SeqQueue(Q,&i);
for(j=0;j<G->vertexNum;j++)
{
if(G->arcs[i][j]<INFINITY!visited[j])//G->arcs[i][j]==1
{
Visit(j);
visited[j]=1;
In_SeqQueue(Q,j);
}
}
}
}
*/
Floyd.cpp:
#include<iostream>
#include"Graph.h"
using namespace std;
void ShortestPath_Floyd(MGraph G,int P[][MaxVertexNum][MaxVertexNum],int D[][MaxVertexNum])
{
//若p[v][w][u]为1表示u是从v到w当前求得的最短路径上的顶点
int u,v,w;
for(v=0;v<G.vertexNum;v++)
for(w=0;w<G.vertexNum;w++)
{
D[v][w]=G.arcs[v][w];
for(u=0;u<G.vertexNum;u++)
P[v][w][u]=0;
if(D[v][w]<INFINITY)
{
P[v][w][v]=1;
P[v][w][w]=1;
}
}
for(u=0;u<G.vertexNum;u++)
for(v=0;v<G.vertexNum;v++)
for(w=0;w<G.vertexNum;w++)
if(D[v][u]+D[u][w]<D[v][w])
{
D[v][w]=D[w][v]=D[v][u]+D[u][w];
P[v][w][u]=1;
}
for(u=0;u<G.vertexNum;u++)
{
for(v=0;v<G.vertexNum;v++)
cout<<D[u][v]<<" ";
cout<<endl;
}
}
void Print_Path(int v,int w,int num,int P[][MaxVertexNum][MaxVertexNum])
{
//显示v到w路径,num为点的数目
int i;
for(i=0;i<num;i++)
if(i!=v&&i!=w&&P[v][w][i]==1)
break;
if(i>=num)
cout<<v<<"->"<<w<<" ";
else
{
Print_Path(v,i,num,P);
Print_Path(i,w,num,P);
}
}
int main()
{
MGraph G=CreatGraph();
int P[MaxVertexNum][MaxVertexNum][MaxVertexNum]={0};
int v,w;
ShortestPath_Floyd(G,P,G.arcs);
cin>>v>>w;
Print_Path(v,w,G.vertexNum,P);
return 0;
}
/*
3 3
0 1 2
0 1 1
0 2 3
1 2 1
0 2
*/
Dijkstra.cpp:
#include<iostream>
#include"Graph.h"
using namespace std;
void ShortestPath_Dij(MGraph G,int v0,int P[],int D[])
{
//迪杰斯特拉算法,求v0到其余各点的最短路径,
//P[v]表示v的前驱结点,D[v]表示v0到v的最短带权路径长度
//final[v]为1表示已找到v0到v的最短路径
int i,v,w;
int min;
int final[MaxVertexNum];
for(v=0;v<=G.vertexNum-1;v++)
{
final[v]=0;
D[v]=G.arcs[v0][v];
P[v]=-1;//初始化表示无前驱
if(D[v]<INFINITY&&v!=v0)
P[v]=v0;
}
D[v0]=0;
final[v0]=1;//初始时v0属于S集
for(i=1;i<=G.vertexNum;i++)
{
v=-1;
min=INFINITY;
for(w=0;w<=G.vertexNum-1;w++)//寻找当前离v0最近的点
if((!final[w])&&D[w]<min)
{
v=w;
min=D[w];
}
if(v==-1)break;//所有与有v0通路的点均已找到最短路径
final[v]=1;//将v加入S集
for(w=0;w<=G.vertexNum-1;w++)//更新当前最短路径及距离
if((!final[w])&&(min+G.arcs[v][w]<D[w]))
{
D[w]=min+G.arcs[v][w];
P[w]=v;//修改w的前驱
}
}
/*for(w=0;w<=G.vertexNum-1;w++)
cout<<w<<" "<<P[w]<<endl;*/
}
void Print_ShortestPath(MGraph G,int v0,int P[],int D[])
{
//显示v0到其他顶点的最短路径及距离
int v,i;
cout<<"The shortest path from Vertex "<<v0<<"to the other Vertex:"<<endl;
for(v=0;v<=G.vertexNum-1;v++)
{
if(P[v]==-1)continue;
printf("%-4d",D[v]);
printf("%d<-",v);
i=v;
while(P[i]!=-1)
{
if(P[P[i]]==-1)
printf("%d",P[i]);
else
printf("%d<-",P[i]);
i=P[i];
}
printf("\n");
}
}
int main()
{
MGraph G=CreatGraph();
int P[MaxVertexNum]={0},D[MaxVertexNum];
int v;
cin>>v;
ShortestPath_Dij(G,v,P,D);
Print_ShortestPath(G,v,P,D);
return 0;
}