Dijkstra最短路径

 

#include<stdio.h>
#define MaxSize 100
#define INF 99999
#define MAXV 6
typedef struct
{
	int edges[MAXV][MAXV];
	int n,e;	
}MatGraph;
void CreatMat(MatGraph &g,int A[MAXV][MAXV],int n,int e)
{
	int i,j;
	g.n=n;g.e=e;
	for(i-0;i<g.n;i++)
	{
		for(j=0;j<g.n;j++)
		g.edges[i][j]=A[i][j];
	}
}
void Dispath(MatGraph g,int dist[],int path[],int S[],int v)// 输出 
{
	int i,j,k;
	int apath[MAXV],d;
	for(i=0;i<g.n;i++)
	{
		if(S[i]==1&&i!=v)
		{
		
		printf("从%d到顶点%d路径长度为 :%d路径为:",v,i,dist[i]);//输出路径长度 
		//接下来是 输出路径 
		d=0;apath[d]=i;// 用 apath数组 记录 从 起点 v到i的 路 
		k=path[i]; // path[i]代表 一条边的 到i的入度 的 点 
		if(k==-1)
		printf("无路径\n");
		else
		{
			while(k!=v)  //不断 记录再 apath[]中 知道 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 minds,i,j,u;
	for(i=0;i<g.n;i++)    //初始化 path[] 
	{
		dist[i]=g.edges[v][i];
		S[i]=0;
		if(g.edges[v][i]<INF)
		path[i]=v;
		else
		path[i]=-1;	
	}
	S[v]=1;path[v]=0; //第一次 赋值 path[]完毕 
	for(i=0;i<g.n-1;i++)
	{
		minds=INF;    // 不断选取 最小的 边 入手  
		for(j=0;j<g.n;j++)
		if(S[j]==0&&dist[j]<minds)
		{
			u=j;
			minds=dist[j];
		}
		
		S[u]=1;  //将取得 最小边的 点 放入 S集合 , (当s[u]=0时 代表改点 在U集合中 s[u]=1代表 放入了 s集合  
		
		for(j=0;j<g.n;j++)
		if(S[j]==0) // u 和j 都在 S集合中 
		{
			if(dist[u]+g.edges[u][j]<dist[j]&&g.edges[u][j]<INF)  //由于进入了 新 的点 u点, 重新 比较 从  u-j 的距离 dist[j] 和 从(0-u)+(u-j)距离的 大小; 
			{
				dist[j]=dist[u]+g.edges[u][j];
				path[j]=u;
			}
		}
		
	}
	Dispath(g,dist,path,S,v);
}

int main()
{
	int v=0;
	MatGraph g;
	int A[MAXV][MAXV]=
	{{0,5,INF,7,INF,INF},
	{INF,0,4,INF,INF,INF},
	{8,INF,0,INF,INF,9},
	{INF,INF,5,0,INF,6},
	{INF,INF,INF,5,0,INF},
	{3,INF,INF,INF,1,0},
	};
	int n=6,e=10;
		CreatMat(g,A,n,e);
	Dijkstra(g,v);
	return 1;
}

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值