主题:[讨论]用dijkstra求最短路径问题,请高手指点一下
此程序只能单向求路径,例如能找到2--5的距离,无法找5--2的距离,请高手指点一下,谢谢
#include<stdio.h>
#include"stdlib.h"
#include"conio.h"
#define inf 65536 //无穷大
#define MAXV 25
int map[MAXV][MAXV]={
{inf ,242 ,inf ,inf ,inf, inf ,inf,inf, inf, inf ,inf ,inf ,inf ,inf ,inf, inf ,inf ,inf ,inf, inf, inf ,inf ,inf ,inf ,inf},
{242 ,inf, 305, inf, inf ,inf ,inf, inf ,inf ,inf, inf ,inf, inf, inf, inf, inf ,inf ,inf, inf, inf ,inf ,inf, inf, inf ,inf},
{inf ,305, inf ,397 ,627, 704, inf, inf, inf, inf ,inf, inf, inf ,inf ,inf ,inf, inf, inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf},
{inf ,inf, 397, inf,inf ,inf, inf ,inf, inf ,inf ,inf ,inf ,inf ,inf, inf,inf ,inf ,inf ,inf ,inf, inf ,inf, inf ,inf ,inf},
{inf ,inf, 627, inf, inf, 137, 668, inf, inf, inf, inf, 695, inf ,inf ,inf ,inf ,inf, inf, inf, inf, inf, inf, inf, inf ,inf},
{inf, inf ,704, inf, 137 ,inf ,inf ,inf ,inf ,inf ,674 ,575, inf ,inf ,inf, inf, inf, inf, inf ,inf ,inf ,inf ,inf,inf,inf},
{inf ,inf ,inf ,inf ,668, inf, inf ,1145 ,inf ,inf ,inf ,694, 774 ,inf, inf ,inf ,inf ,inf, inf ,inf ,inf, inf ,inf ,inf, inf},
{inf ,inf, inf, inf ,inf ,inf ,1145, inf, 1892, 216, inf ,inf ,676,inf ,inf, 601 ,inf ,inf, inf ,inf ,inf,inf,inf,inf,inf},
{inf ,inf, inf, inf ,inf ,inf ,inf ,1892 ,inf, inf, inf, inf ,inf ,inf ,inf ,inf, inf, inf, inf ,inf ,inf ,inf ,inf, inf, inf},
{inf, inf ,inf, inf ,inf ,inf ,inf ,216 ,inf, inf, inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf, inf ,inf ,inf ,inf ,inf ,inf},
{inf ,inf ,inf ,inf, inf, 674, inf, inf ,inf, inf ,inf ,349, inf ,651, inf ,inf ,inf, inf ,inf, inf ,inf ,inf ,inf, inf ,inf},
{inf ,inf, inf, inf ,695 ,575 ,694 ,inf ,inf ,inf ,349, inf ,511 ,829 ,534 ,inf, inf ,inf ,inf ,inf ,inf, inf ,inf ,inf ,inf},
{inf, inf, inf ,inf, inf, inf ,774 ,1145, inf ,inf ,inf, 511, inf ,inf, 650, 842, inf ,inf ,inf ,inf, inf,inf ,inf, inf, inf},
{inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,651 ,829 ,inf ,inf ,688 ,inf ,609 ,825, inf ,inf ,inf ,inf ,inf ,inf, inf},
{inf ,inf ,inf ,inf, inf ,inf, inf, inf ,inf ,inf ,inf ,534 ,650, 688, inf ,977 ,inf ,263, 409, inf, inf ,inf ,inf ,inf ,inf},
{inf ,inf ,inf ,inf ,inf ,inf ,inf ,601 ,inf ,inf ,inf ,inf ,842 ,inf ,977 ,inf ,inf ,inf, inf ,967 ,1100 ,inf, inf ,inf ,inf},
{inf ,inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 609, inf, inf, inf, 622, inf, inf, inf, 693, inf, inf, inf},
{inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,825 ,263 ,inf ,622 ,inf ,367 ,inf ,inf ,673 ,inf ,inf ,inf},
{inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 409, inf, inf, 367, inf, 902, inf, 675, 672, inf, inf},
{inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf, inf ,967 ,inf ,inf ,902 ,inf ,639 ,inf ,607 ,inf ,inf},
{inf ,inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 1100, inf, inf, inf, 639, inf, inf, inf, inf, 629},
{inf ,inf ,inf ,inf ,inf ,inf ,inf, inf ,inf, inf ,inf ,inf ,inf ,inf ,inf ,inf ,693 ,673 ,675 ,inf ,inf ,inf ,inf ,140 ,506},
{inf ,inf, inf, inf, inf, inf ,inf, inf, inf, inf, inf, inf, inf, inf, inf, inf ,inf, inf, 672, 607, inf, inf, inf, inf, 255},
{inf ,inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 140, inf, inf, inf},
{inf ,inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 629 ,inf, 255, 506, inf}
};
struct station
{
int number;
char name[10];
}Station[25]=
{
{1,"哈尔滨"},{2,"长春"},{3,"沈阳"},{4,"大连"},{5,"北京"},{6,"天津"},{7,"呼和浩特"},{8,"兰州"},{9,"乌鲁木齐"},{10,"西宁"},
{11,"徐州"},{12,"郑州"},{13,"西安"},{14,"上海"},{15,"武汉"},{16,"成都"},{17,"福州"},{18,"南昌"},{19,"株州"},{20,"贵阳"},
{21,"昆明"},{22,"广州"},{23,"柳州"},{24,"深圳"},{25,"南宁"}
};
int s,d,temp=0;
void Path(int path[],int i,int v0)
{
int k;
k=path[i];
if(k==v0) return;
Path(path,k,v0);
printf("<-->%s",Station[path[i]].name);
}
void Print(int dis[],int path[],int s[],int v0)//输出从源点到每一个可达点的距离
{
system("cls");
printf("\n\n从 %s 到 %s 的最短路径长度为:%d千米\n\n",Station[v0].name,Station[d-1].name,dis[d-1]);
printf("\n线路: %s ",Station[v0].name);
Path(path,d-1,v0);
printf("<-->%s\n\n",Station[d-1].name);
}
void Dijkstra(int n,int v0) //n为顶点个数,v0为源点
{
int dis[MAXV], path[MAXV]; //dis[i]保存从源点到终点vi目前最短路径的长度
//path[i]保存从源点v0到达i点的最短路径上该点的前趋顶点
int s[MAXV]; //已找到时最短路径的点
int min,i,j,k;
for(i=0;i<n;i++) //距离初始化
{
dis[i]=map[v0][i];
s[i]=0;
if(map[v0][i]<inf)
path[i]=v0;
else
path[i]=0;
}
s[v0]=1;
dis[v0]=0;
for(i=0;i<n-1;i++)
{//选取不在S中且有最小距离的顶点u
min=inf;
for(j=0;j<n;j++)
{
if(!s[j]&&dis[j]<min)
{
k=j;
min=dis[j];
}
}
s[k]=1;
//修改不在S中的顶点的距离
for(j=0;j<n;j++)
{
if(!s[j]&&dis[k]+map[k][j]<dis[j])
{
dis[j]=dis[k]+map[k][j];
path[j]=k;
}
}
}
Print(dis,path,s,v0); //输出最短路径
}
void Start_select()
{
while(temp==0)
{
system("cls");
printf("\n 起 点 站\n");
printf("\n ======================================================================\n");
printf("\n 1、 哈尔滨 2、 长春 3、 沈阳 4、 大连 5、 北京\n");
printf("\n 6、 天津 7、 呼和浩特 8、 兰州 9、 乌鲁木齐 10、西宁\n");
printf("\n 11、徐州 12、郑州 13、西安 14、上海 15、武汉 \n");
printf("\n 16、成都 17、福州 18、南昌 19、株州 20、贵阳\n");
printf("\n 21、昆明 22、广州 23、柳州 24、深圳 25、南宁\n");
printf("\n ======================================================================\n");
printf("\n 请选择起点站:");
scanf("%d",&s);
if(s<1||s>25)
{
printf("\n ERROR:输入错误,请重新选择!\n\n");
getch();//从控制台读取一个字符,但不显示在屏幕上
}
else temp=1;
}
}
void Destination_select()
{
while(temp==1)
{
system("cls");
printf("\n 终 点 站\n");
printf("\n ======================================================================\n");
printf("\n 1、 哈尔滨 2、 长春 3、 沈阳 4、 大连 5、 北京\n");
printf("\n 6、 天津 7、 呼和浩特 8、 兰州 9、 乌鲁木齐 10、西宁\n");
printf("\n 11、徐州 12、郑州 13、西安 14、上海 15、武汉 \n");
printf("\n 16、成都 17、福州 18、南昌 19、株州 20、贵阳\n");
printf("\n 21、昆明 22、广州 23、柳州 24、深圳 25、南宁\n");
printf("\n ======================================================================\n");
printf("\n 请选择终点站:");
scanf("%d",&d);
if(d<1||d>25)
{
printf("\n ERROR:输入错误,请重新选择!\n\n");
getch();
}
else temp=0;
}
}
int Select()
{
if(s==d)
{
printf("\n ERROR:起点站和终点站相同,请重新选择!\n\n");
getch();
temp=0;
}
else temp=1;
return temp;
}
void Quit();
void Shortest()
{
while(temp==0)
{
Start_select();
Destination_select();
Select();
}
Dijkstra(d,s-1);
Quit();
}
void Quit()
{
char reply;
printf("\n继续吗?(y/n):");
getchar();
if(getchar()=='y')
{
temp=0;
Shortest();
}
else exit(0);//结束应用程序
}
void main()
{
Shortest();
}
#include<stdio.h>
#include"stdlib.h"
#include"conio.h"
#define inf 65536 //无穷大
#define MAXV 25
int map[MAXV][MAXV]={
{inf ,242 ,inf ,inf ,inf, inf ,inf,inf, inf, inf ,inf ,inf ,inf ,inf ,inf, inf ,inf ,inf ,inf, inf, inf ,inf ,inf ,inf ,inf},
{242 ,inf, 305, inf, inf ,inf ,inf, inf ,inf ,inf, inf ,inf, inf, inf, inf, inf ,inf ,inf, inf, inf ,inf ,inf, inf, inf ,inf},
{inf ,305, inf ,397 ,627, 704, inf, inf, inf, inf ,inf, inf, inf ,inf ,inf ,inf, inf, inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf},
{inf ,inf, 397, inf,inf ,inf, inf ,inf, inf ,inf ,inf ,inf ,inf ,inf, inf,inf ,inf ,inf ,inf ,inf, inf ,inf, inf ,inf ,inf},
{inf ,inf, 627, inf, inf, 137, 668, inf, inf, inf, inf, 695, inf ,inf ,inf ,inf ,inf, inf, inf, inf, inf, inf, inf, inf ,inf},
{inf, inf ,704, inf, 137 ,inf ,inf ,inf ,inf ,inf ,674 ,575, inf ,inf ,inf, inf, inf, inf, inf ,inf ,inf ,inf ,inf,inf,inf},
{inf ,inf ,inf ,inf ,668, inf, inf ,1145 ,inf ,inf ,inf ,694, 774 ,inf, inf ,inf ,inf ,inf, inf ,inf ,inf, inf ,inf ,inf, inf},
{inf ,inf, inf, inf ,inf ,inf ,1145, inf, 1892, 216, inf ,inf ,676,inf ,inf, 601 ,inf ,inf, inf ,inf ,inf,inf,inf,inf,inf},
{inf ,inf, inf, inf ,inf ,inf ,inf ,1892 ,inf, inf, inf, inf ,inf ,inf ,inf ,inf, inf, inf, inf ,inf ,inf ,inf ,inf, inf, inf},
{inf, inf ,inf, inf ,inf ,inf ,inf ,216 ,inf, inf, inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf, inf ,inf ,inf ,inf ,inf ,inf},
{inf ,inf ,inf ,inf, inf, 674, inf, inf ,inf, inf ,inf ,349, inf ,651, inf ,inf ,inf, inf ,inf, inf ,inf ,inf ,inf, inf ,inf},
{inf ,inf, inf, inf ,695 ,575 ,694 ,inf ,inf ,inf ,349, inf ,511 ,829 ,534 ,inf, inf ,inf ,inf ,inf ,inf, inf ,inf ,inf ,inf},
{inf, inf, inf ,inf, inf, inf ,774 ,1145, inf ,inf ,inf, 511, inf ,inf, 650, 842, inf ,inf ,inf ,inf, inf,inf ,inf, inf, inf},
{inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,651 ,829 ,inf ,inf ,688 ,inf ,609 ,825, inf ,inf ,inf ,inf ,inf ,inf, inf},
{inf ,inf ,inf ,inf, inf ,inf, inf, inf ,inf ,inf ,inf ,534 ,650, 688, inf ,977 ,inf ,263, 409, inf, inf ,inf ,inf ,inf ,inf},
{inf ,inf ,inf ,inf ,inf ,inf ,inf ,601 ,inf ,inf ,inf ,inf ,842 ,inf ,977 ,inf ,inf ,inf, inf ,967 ,1100 ,inf, inf ,inf ,inf},
{inf ,inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 609, inf, inf, inf, 622, inf, inf, inf, 693, inf, inf, inf},
{inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,825 ,263 ,inf ,622 ,inf ,367 ,inf ,inf ,673 ,inf ,inf ,inf},
{inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 409, inf, inf, 367, inf, 902, inf, 675, 672, inf, inf},
{inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf ,inf, inf ,967 ,inf ,inf ,902 ,inf ,639 ,inf ,607 ,inf ,inf},
{inf ,inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 1100, inf, inf, inf, 639, inf, inf, inf, inf, 629},
{inf ,inf ,inf ,inf ,inf ,inf ,inf, inf ,inf, inf ,inf ,inf ,inf ,inf ,inf ,inf ,693 ,673 ,675 ,inf ,inf ,inf ,inf ,140 ,506},
{inf ,inf, inf, inf, inf, inf ,inf, inf, inf, inf, inf, inf, inf, inf, inf, inf ,inf, inf, 672, 607, inf, inf, inf, inf, 255},
{inf ,inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 140, inf, inf, inf},
{inf ,inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 629 ,inf, 255, 506, inf}
};
struct station
{
int number;
char name[10];
}Station[25]=
{
{1,"哈尔滨"},{2,"长春"},{3,"沈阳"},{4,"大连"},{5,"北京"},{6,"天津"},{7,"呼和浩特"},{8,"兰州"},{9,"乌鲁木齐"},{10,"西宁"},
{11,"徐州"},{12,"郑州"},{13,"西安"},{14,"上海"},{15,"武汉"},{16,"成都"},{17,"福州"},{18,"南昌"},{19,"株州"},{20,"贵阳"},
{21,"昆明"},{22,"广州"},{23,"柳州"},{24,"深圳"},{25,"南宁"}
};
int s,d,temp=0;
void Path(int path[],int i,int v0)
{
int k;
k=path[i];
if(k==v0) return;
Path(path,k,v0);
printf("<-->%s",Station[path[i]].name);
}
void Print(int dis[],int path[],int s[],int v0)//输出从源点到每一个可达点的距离
{
system("cls");
printf("\n\n从 %s 到 %s 的最短路径长度为:%d千米\n\n",Station[v0].name,Station[d-1].name,dis[d-1]);
printf("\n线路: %s ",Station[v0].name);
Path(path,d-1,v0);
printf("<-->%s\n\n",Station[d-1].name);
}
void Dijkstra(int n,int v0) //n为顶点个数,v0为源点
{
int dis[MAXV], path[MAXV]; //dis[i]保存从源点到终点vi目前最短路径的长度
//path[i]保存从源点v0到达i点的最短路径上该点的前趋顶点
int s[MAXV]; //已找到时最短路径的点
int min,i,j,k;
for(i=0;i<n;i++) //距离初始化
{
dis[i]=map[v0][i];
s[i]=0;
if(map[v0][i]<inf)
path[i]=v0;
else
path[i]=0;
}
s[v0]=1;
dis[v0]=0;
for(i=0;i<n-1;i++)
{//选取不在S中且有最小距离的顶点u
min=inf;
for(j=0;j<n;j++)
{
if(!s[j]&&dis[j]<min)
{
k=j;
min=dis[j];
}
}
s[k]=1;
//修改不在S中的顶点的距离
for(j=0;j<n;j++)
{
if(!s[j]&&dis[k]+map[k][j]<dis[j])
{
dis[j]=dis[k]+map[k][j];
path[j]=k;
}
}
}
Print(dis,path,s,v0); //输出最短路径
}
void Start_select()
{
while(temp==0)
{
system("cls");
printf("\n 起 点 站\n");
printf("\n ======================================================================\n");
printf("\n 1、 哈尔滨 2、 长春 3、 沈阳 4、 大连 5、 北京\n");
printf("\n 6、 天津 7、 呼和浩特 8、 兰州 9、 乌鲁木齐 10、西宁\n");
printf("\n 11、徐州 12、郑州 13、西安 14、上海 15、武汉 \n");
printf("\n 16、成都 17、福州 18、南昌 19、株州 20、贵阳\n");
printf("\n 21、昆明 22、广州 23、柳州 24、深圳 25、南宁\n");
printf("\n ======================================================================\n");
printf("\n 请选择起点站:");
scanf("%d",&s);
if(s<1||s>25)
{
printf("\n ERROR:输入错误,请重新选择!\n\n");
getch();//从控制台读取一个字符,但不显示在屏幕上
}
else temp=1;
}
}
void Destination_select()
{
while(temp==1)
{
system("cls");
printf("\n 终 点 站\n");
printf("\n ======================================================================\n");
printf("\n 1、 哈尔滨 2、 长春 3、 沈阳 4、 大连 5、 北京\n");
printf("\n 6、 天津 7、 呼和浩特 8、 兰州 9、 乌鲁木齐 10、西宁\n");
printf("\n 11、徐州 12、郑州 13、西安 14、上海 15、武汉 \n");
printf("\n 16、成都 17、福州 18、南昌 19、株州 20、贵阳\n");
printf("\n 21、昆明 22、广州 23、柳州 24、深圳 25、南宁\n");
printf("\n ======================================================================\n");
printf("\n 请选择终点站:");
scanf("%d",&d);
if(d<1||d>25)
{
printf("\n ERROR:输入错误,请重新选择!\n\n");
getch();
}
else temp=0;
}
}
int Select()
{
if(s==d)
{
printf("\n ERROR:起点站和终点站相同,请重新选择!\n\n");
getch();
temp=0;
}
else temp=1;
return temp;
}
void Quit();
void Shortest()
{
while(temp==0)
{
Start_select();
Destination_select();
Select();
}
Dijkstra(d,s-1);
Quit();
}
void Quit()
{
char reply;
printf("\n继续吗?(y/n):");
getchar();
if(getchar()=='y')
{
temp=0;
Shortest();
}
else exit(0);//结束应用程序
}
void main()
{
Shortest();
}