图
图的最短路径
在有向图中,如果每条有向边都赋了权值,则称该图为赋权有向图.
求图中某顶点到其他顶点具有最小权值总和的路径,称为最短路径问题(MPL)
若将边所赋予的权值,理解为边的长度,那么最短路径问题就可以描述为:
从图中某一顶点出发,沿着图中的边,找一条到达其他顶点的路径,
使得所经过的边的总长度最小.
我们可以Dijkstra算法解决该问题.
#include<iostream>
using namespace std;
#define MaxSize 20
#define inf 2147483647
struct Graph{
int V[MaxSize];
int M[MaxSize][MaxSize];
int n;
};
void Create(Graph &G,int *V,int vn,int *E,int en,int action){
int i,j,k,w;
G.n=vn;
for(i=0;i<G.n;i++)
G.V[i]=V[i];
for(i=0;i<G.n;i++){
for(j=0;j<G.n;j++)
if(i==j)
G.M[i][j]=0;
else
G.M[i][j]=inf;
}
for(k=0;k<en;k++){
i=E[3*k+0];
j=E[3*k+1];
w=E[3*k+2];
G.M[i][j]=w;
if(action==0)
G.M[j][i]=w;
}
}
void Display1(Graph G){
int i,j;
cout<<"顶点"<<"\t";
for(i=0;i<G.n;i++)
cout<<"V"<<G.V[i]<<"\t";
cout<<endl;
for(i=0;i<G.n;i++){
cout<<"V"<<G.V[i]<<"\t";
for(j=0;j<G.n;j++)
if(G.M[i][j]==inf)
cout<<"inf"<<"\t";
else
cout<<G.M[i][j]<<"\t";
cout<<endl;
}
}
void MPL(Graph G,int U[],int dist[],int path[],int sv){
int i,j,k,min;
for(j=0;j<G.n;j++){
dist[j]=G.M[sv][j];
if(j==sv) U[j]=1;
else U[j]=0;
if(G.M[sv][j]!=inf) path[j]=sv;
else path[j]=-1;
}
for(i=0;i<G.n;i++){
min=inf;
k=-1;
for(j=0;j<G.n;j++)
if(U[j]==0&&dist[j]<min){
k=j;
min=dist[j];
}
U[k]=1;
for(j=0;j<G.n;j++){
if(U[j]==0)
if(G.M[k][j]<inf&&dist[k]+G.M[k][j]<dist[j]){
dist[j]=dist[k]+G.M[k][j];
path[j]=k;
}
}
}
}
void Display(int dist[],int path[],int sv,int ev){
if(path[ev]==-1){
cout<<"没有从起点"<<sv<<"到终点"<<ev<<"的路径"<<endl;
return;
}
if(path[ev]==ev)
cout<<"V"<<ev;
else{
Display(dist,path,sv,path[ev]);
cout<<"=>V"<<ev;
}
}
int main(){
int V[5]={0,1,2,3,4};
int E[7][3]={{0,1,3},{0,2,4},{1,2,6},{2,3,1},{2,4,7},{3,0,5},{3,4,2}};
Graph G;
Create(G,&V[0],5,&E[0][0],7,1);
cout<<"图的领接矩阵"<<endl;
Display1(G);
int sv=0;
int U[MaxSize],dist[MaxSize],path[MaxSize];
MPL(G,U,dist,path,sv);
for(int i=0;i<G.n;i++){
cout<<"V"<<sv<<"=>V"<<i<<"最短路径长度:"<<dist[i]<<endl;
cout<<"最短路径:";
Display(dist,path,sv,i);
cout<<endl;
}
}