数据结构实验:最短路径

该实验涉及计算有向带权图中从特定顶点到所有其他顶点的最短路径。通过对用户输入的图进行处理,应用相应的数据结构和算法来找到这些路径。

实验内容:对于用户随机输入的一个有向带权图,求从某个顶点到其他各顶点的最短路径。

 

#include<stdio.h>
#define MAXV 20
#define INF 32	            //若<vi,vj>不存在,则设<vi,vj>的权为32,表示无穷大
typedef struct 
{      int no;				/*顶点编号*/
       //  InfoType info;   /*顶点其他信息,此处省略*/
} VertexType;		    	/*顶点类型*/
typedef struct  		            
{      int edges[MAXV][MAXV];    	/*邻接矩阵*/
       int n,e;                     /*顶点数,边数*/
       VertexType vexs[MAXV];   	/*存放顶点信息*/
}MatGraph;                          /*完整的图邻接矩阵类型*/

void Dispath(MatGraph g,int dist[],int path[],int s[],int v)
{  int i,j,k;
   int apath[MAXV],d;
   printf("\n");
   for(i=0;i<g.n;i++)
	 if(s[i]==1 && i!=v)
	 {  printf("从顶点%d到顶点%d的路径长度为:%d\t路径为:",v,i,dist[i]);
	    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]);
		for(j=d-1;j>=0;j--)
		   printf(",%d",apath[j]);
		printf("\n");
		}
	 }
}

void Dijkstra(MatGraph g,int v)
{  int dist[MAXV],path[MAXV];
   int s[MAXV];
   int mindis,i,j,u;
   for (i=0;i<g.n;i++)
   {  dist[i]=g.edges[v][i];	//距离初始化
	  s[i]=0;			        //s[]置空
	  if(g.edges[v][i]<INF)	    //路径初始化
	    path[i]=v;              //顶点v到i有边时,置顶点i的前一个顶点为v
 	  else
	    path[i]=-1;             //顶点v到i没边时,置顶点i的前一个顶点为-1
   }
   s[v]=1;path[v]=0;            //源点编号v放入s中
   for(i=0;i<g.n-1;i++)	        //循环直到所有顶点的最短路径都求出
   {  mindis=INF;		        //mindis置最小长度初值
	  for(j=0;j<g.n;j++)        //选取不在s中且具有最小距离的顶点u
	     if(s[j]==0 && dist[j]<mindis) 
		 {  u=j;
		    mindis=dist[j];
		 }
	  s[u]=1;		        	//顶点u加入s中
	  for(j=0;j<g.n;j++)	    //修改不在s中的顶点的距离
	     if(s[j]==0)
	        if(g.edges[u][j]<INF && dist[u]+g.edges[u][j]<dist[j])
			{  dist[j]=dist[u]+g.edges[u][j];
	   	       path[j]=u;
			}
   }
   Dispath(g,dist,path,s,v);    //输出最短路径
}

void main()
{  MatGraph G;
   int V,i,j;
   printf("请输入图G的顶点数和边数(用逗号分隔):");
   scanf("%d,%d",&G.n,&G.e);
   getchar();
   printf("请输入图G的顶点编号(用空格分隔):");
   for(i=0;i<G.n;i++)
	 scanf("%d",&G.vexs[i].no);
   getchar();
   printf("请分行输入图G的邻接矩阵(同一行的元素用空格分隔,每输入完一行按回车结束):\n");
   for(i=0;i<G.n;i++)
   {  for(j=0;j<G.n;j++)
        scanf("%d",&G.edges[i][j]);
      getchar();
   }
   printf("请输入源点V的编号:");
   scanf("%d",&V);
   Dijkstra(G,V);
}
请输入图G的顶点数和边数(用逗号分隔):5,8
请输入图G的顶点编号(用空格分隔):0 1 2 3 4
请分行输入图G的邻接矩阵(同一行的元素用空格分隔,每输入完一行按回车结束):
0 1 0 1 1
1 0 1 1 0
0 1 0 1 1
1 1 1 0 1
1 0 1 1 0
请输入源点V的编号:0

从顶点0到顶点1的路径长度为:1 路径为:0,1
从顶点0到顶点2的路径长度为:0 路径为:0,2
从顶点0到顶点3的路径长度为:1 路径为:0,3
从顶点0到顶点4的路径长度为:1 路径为:0,4

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值