求图的最短路径 数据结构(C语言)

mosty 2008-06-03 10:17:58
1、建立b到a权为10 a到b权为5,b到d权为1,b到c权为6 c到a权为3 c到d权为4,d到c权为2,d到b权为8的图
2、求出指定起点(由键盘输入)到终点(指定)的最短路径;
[基本要求]
1、采用邻接矩阵为存储结构;
2、有较好的交互界面完成输入(如起点的指定)和输出;
3、输出的最短路径应该包括2方面内容:首先,最短路径长度是多少;其次,该最短路径经过了哪些顶点。
...全文
3146 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Paradin 2009-05-02
  • 打赏
  • 举报
回复
up
光宇广贞 2009-05-02
  • 打赏
  • 举报
回复
[Quote=引用楼主 mosty 的帖子:]
  1、建立b到a权为10 a到b权为5,b到d权为1,b到c权为6 c到a权为3 c到d权为4,d到c权为2,d到b权为8的图
2、求出指定起点(由键盘输入)到终点(指定)的最短路径;
[基本要求]
1、采用邻接矩阵为存储结构;
2、有较好的交互界面完成输入(如起点的指定)和输出;
3、输出的最短路径应该包括2方面内容:首先,最短路径长度是多少;其次,该最短路径经过了哪些顶点。

[/Quote]

我觉得你是让我们去猜这是一种什么算法的体现……

答案是 Dijkstra 算法……

学过数据结构和算法的人就应该对此刻骨铭心的……

你的问题等于把该算法重述了一遍……无论数据结构上,输入和输出上……

自己去看书吧……

请记住,它叫做 Dijkstra 算法!
是学计算机的么…………………………………………………………………………
bbcby 2009-05-02
  • 打赏
  • 举报
回复
我就是图学的垃圾
liberpc 2008-12-26
  • 打赏
  • 举报
回复
学习了
codesnail 2008-12-26
  • 打赏
  • 举报
回复
ding! mark!
学习了!
lin350176641 2008-12-24
  • 打赏
  • 举报
回复

我是初学者
K行天下 2008-06-06
  • 打赏
  • 举报
回复
自己上网搜吧!遇到具体可以贴出来一起讨论!
laolaoliu2002 2008-06-06
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INFINITY 0
#define MAX_VERTEX_NUM 20
#define MAX_SIZE 10000
typedef enum {DG,DN,UDG,UDN} GraphKind;
typedef struct ArcCell{
int adj;
char * info;
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
int vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum,arcnum;
GraphKind kind;
}MGraph;
//-------
int LocateVex(int vexs[],int v){ //确定节点v在节点向量中的位置
for(int i=0;i<MAX_VERTEX_NUM;i++)
if(vexs[i]==v)
return i;
printf("不存在这个节点!");
exit(0);
}
bool CreateD(MGraph &G){
int IncInfo,v1,v2,w,i,j,k;
printf("请输入有向图的顶点数和弧数,以及各弧是否含有其他信息(0表示不含其它信息)\n");
scanf("%d%d%d",&G.vexnum,&G.arcnum,&IncInfo);
for(i=0;i<G.vexnum;i++) //初始化节点向量
G.vexs[i]=i+1;
for(i=0;i<G.vexnum;i++){ //初始化邻接矩阵
for(j=0;j<G.vexnum;j++){
G.arcs[i][j].adj=INFINITY; G.arcs[i][j].info=NULL;
}
}
for(k=0;k<G.arcnum;k++){ //输入一条边及依附的定点及权值
printf("请输入第%d弧的两个节点及权值:",k+1);
scanf("%d%d%d",&v1,&v2,&w);
i=LocateVex(G.vexs,v1); j=LocateVex(G.vexs,v2); //找到两个顶点在邻接矩阵中的位置
G.arcs[i][j].adj=w;
if(IncInfo)
scanf("%s",G.arcs[i][j].info); //若弧含有相关信息,则输入信息
}
return true;
}
//---------------------------------------------------
bool final[MAX_VERTEX_NUM]={false}; //用于标记到顶点i的最短路径是否已经找到
bool P[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int D[MAX_VERTEX_NUM]={0};
void ShortestPath_DIJ(MGraph G,int v0){
int i,w,v;
for(v=0;v<G.vexnum;v++){
D[v]=G.arcs[v0][v].adj;
for(w=0;w<G.vexnum;w++)
P[v][w]=false;
if(D[v]<MAX_SIZE){
P[v][v0]=true; P[v][v]=true;
}
}
D[v0]=0; final[v0]=true;
for(i=1;i<G.vexnum;i++){
int min=MAX_SIZE;
for(w=0;w<G.vexnum;w++)
if(!final[w])
if(D[w]<min){
min=D[w]; v=w;
}
final[v]=true;
for(w=0;w<G.vexnum;w++)
if(!final[w]&&(min+G.arcs[v][w].adj<D[w])){
D[w]=min+G.arcs[v][w].adj;
for(i=0;i<G.vexnum;i++)
P[w][i]=P[v][i];
P[w][w]=true;
}
}
}
int main(){


MGraph G;
CreateD(G);
int v0;
printf("请输入始点:");
scanf("%d",&v0);
ShortestPath_DIJ(G,v0-1);
for(int i=0;i<G.vexnum;i++){
if(i!=v0-1){
printf("V%d to V%d is:",v0,i+1);
printf("<");
for(int j=0;j<G.vexnum;j++)
if(P[i][j]&&j!=i)
printf("V%d,",j+1);
printf("V%d>",i+1);
printf("--Length is:%d\n",D[i]);
}
}
return 0;
}
laolaoliu2002 2008-06-06
  • 打赏
  • 举报
回复
Dijkstra算法 http://baike.baidu.com/view/7839.htm
A*算法 http://baike.baidu.com/view/7850.html
Bellman-Ford算法 http://baike.baidu.com/view/1481053.html
laolaoliu2002 2008-06-06
  • 打赏
  • 举报
回复
http://www.gisforum.net/show.aspx?id=816&cid=30
天亮后说晚安 2008-06-06
  • 打赏
  • 举报
回复
好手
des2006 2008-06-04
  • 打赏
  • 举报
回复
不是有个dijkstra算法么

你可以在网上搜一下他的实现,估计改改就能用
9527他大爷 2008-06-03
  • 打赏
  • 举报
回复
make
aSpace 2008-06-03
  • 打赏
  • 举报
回复
这些东西,搜索一下就n多了。。
wuyu637 2008-06-03
  • 打赏
  • 举报
回复
给定一个(无向)图G,及G中的两点s、t,确定一条从s到t的最短路径。

输入图G的顶点数n。接下来的n行描述这一个图形,采用邻接表方式,其中的第i行有n个数,依次表示第i个顶点与第1、2、3、…、n个顶点的路径长。假如两个顶点间无边相连,用一个大数maxint(如65535)表示。再在下面的一行上给出两个整数i、j表示要求最短距离的两个顶点i和顶点j。
输出两个顶点i和顶点j的最短距离,同时给出最短路径上的顶点序列。
注意:每行上的两个相邻数间用一个空格隔开。

实验结果:
输入
4
0 2 65535 4
2 0 3 65535
65535 3 0 2
4 65535 2 0
1 3

输出
The least distance from l to 3 is 5.
The path is 1-> 2-> 3

程序代码:

#include<iostream>
#include<cstdlib>
using namespace std;

void Dijkstra(int n,int v,int dist[],int prev[],int **c)
{
int maxint = 65535;
bool *s = new bool[n];
for (int i = 1; i <= n; i++)
{
dist[i] = c[v][i];
s[i] = false;
if (dist[i] == maxint)
{
prev[i] = 0;
}
else
{
prev[i] = v;
}
}
dist[v] = 0;
s[v] = true;
for (int i = 1; i < n; i++)
{
int temp = maxint;
int u = v;
for (int j = 1; j <= n; j++)
{
if ((!s[j]) && (dist[j] < temp))
{
u = j;
temp = dist[j];
}
}
s[u] = true;
for (int j = 1; j <= n; j++)
{
if ((!s[j]) && (c[u][j] < maxint))
{
int newdist = dist[u] + c[u][j];
if (newdist < dist[j])
{
dist[j] = newdist;
prev[j] = u;
}
}
}
}
}

int main()
{
int n,v,u;
int q = 0;
cout<<"输入顶点数:";
cin>>n;
int *way = new int[n + 1];
int **c = new int *[n + 1];
for (int i = 1; i <= n; i++)
{
c[i] = new int[n + 1];
}
cout<<"输入顶点的邻接矩阵:";
for (int j = 1; j <= n; j++)
{
for (int t = 1; t <= n; t++)
{
cin>>c[j][t];
}
}
int *dist = new int [n];
int *prev = new int [n];
cout<<"输入出发点和到达点:";
cin>>v>>u;
Dijkstra(n, v, dist, prev, c);
cout<<"最短路径从"<<v<<" -> "<<u<<" 的距离是:"<<dist[u]<<endl;
int w = u;
while (w != v)
{
q++;
way[q] = prev[w];
w = prev[w];
}
cout<<"路径为:";
for (int j = q; j >= 1; j--)
{
cout<<way[j]<<" ->";
}
cout<<u<<endl;

delete []way; way=NULL;
for (int i = 1; i <= n; i++) delete []c[i];
delete []c;
c=NULL;
delete []dist; dist=NULL;
delete []prev; prev=NULL;
system("pause");
return 0;
}

程序分析:
a[i][j]记边(i,j)的权,数组dist[u]记从源v到顶点u所对应的最短特殊路径长度
算法描述如下:
S1:初始化,S, T,对每个yS,{dist[y]=a[v][y],prev[y]=nil}
S2:若S=V,则输出dist,prev,结束
S3:uV\S中有最小dist值的点,SS{u}
S4:对u的每个相邻顶点x,调整dist[x]:即
若dist[x]>dist[u]+a[u][x],则{dist[x]=dist[u]+a[u][x],prev[x]=u},转S2

对于具有n个顶点和e条边的带权有向图,如果用带权邻接矩阵表示这个图,那么Dijkstra算法的主循环体需要O(n)时间。这个循环需要执行n-1次,所以完成循环需要O(n2)时间。算法的其余部分所需要时间不超过O(n2)

69,368

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧