Dijkstra

Dijkstra算法牵涉到几个非常重要的状态变量
1)长度为N的一维数组Dist[N],用来存放从源点到图中其它节点的最短路径长度;
2)Dijkstra算法需要维护两个非常重要的集合,假设这两个集合分别为V和S,V集合用来存放目前还没有计算节点,S集合用来存放已经得到最短路径的节点集合。刚开始时,集合V包含图中所有节点,集合S为空。
3)辅助二维数组path_matrix,用来记录源点到图中其它每个节点的最短路径所经过的顶点结合。

Dijkstra算法执行流程;
1 初始化集合V和S;
2 利用图的邻接矩阵来初始化Dist[N]数组;
3 从Dist[N]数组中选择最小的元素,假设此最小元素对应的节点编号为i,即节点i;
4 将节点i加入集合S中,同时从集合V中删除节点i;
5 根据节点i来更新距离数组Dist[N],只更新源点到那些处于集合V-S中的节点之间的距离;
if (Dist[j] > Dist[i]+matrix[i][j] )
Dist[j]=Dist[i]+matrix[i][j];
6 回到3执行,直至集合V为空。

模板:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Max 1005
#define Inf 1000000000


int distMatrix[Max][Max];
int n;
int m;

void dijkstra(int d[],int p[],int v)
{
 	 int *visited = (int *)malloc(sizeof(int) * n);
 	 for(int i = 1;i <= n;i++)
 	 {
	  		 visited[i] = 0;
	  		 if(distMatrix[v][i] > 0 && i != v)
	  		 {
 				 d[i] = distMatrix[v][i];
 				 p[i] = v;
		     }
		     else
		     {
			  	 d[i] = Inf;
			  	 p[i] = -1;
		  	 }
     }
     visited[v] = 1;
     d[v] = 0;
     p[v] = v;
	 
	 for(int i = 0;i < n ;i++)
	 {
	  		 int k,min=Inf;
	  		 //寻找出距离v最近的点和距离 
	  		 for(int j = 1;j <= n; j++)
	  		 {
			  		 if(visited[j] == 0 && d[j] < min)
			  		 {
					  	min = d[j];
			  		 	k = j;   
             		 }
	  		 }
	  		 //更新v到(还未找出最短距离)顶点的距离(最短) 
	  		 visited[k] = 1;
	  		 for(int j = 1;j <= n; j++)
	  		 {
			  		 if(visited[j] == 0 && distMatrix[k][j] > 0 && d[k] + distMatrix[k][j] < d[j])//由于两点之间无距离时,我们设置的是0,故在此需要判断 
			  		 {
   		   			  			   d[j] = d[k] + distMatrix[k][j];
					  			   p[j] = k;	  
  			   		 }
	  		 }
	 }
}

void showpath(int p[],int s,int t)
{
 	 int que[Max];
	 int tot = 1;
	 que[tot] = t;
	 tot++;
	 int tmp = p[t];
	 while(tmp != s)
	 {
  	  		   que[tot] = tmp;
			   tot++;
			   tmp = p[tmp];
	}
	que[tot] = s;
	for(int i=tot; i>=1; --i)
		if(i != 1)
			printf("%d -> ",que[i]);
		else
			printf("%d\n",que[i]);
} 

int main()
{
 	int a,b,d,s,t;
 	while(scanf("%d %d",&n,&m) != EOF && n != 0 && m != 0)
 	{
	 				int *dist = (int *)malloc(sizeof(int) * n);
		 			int *path = (int *)malloc(sizeof(int) * n);
	 				//初始化 假设点号从1开始的 
	 				for(int i = 1;i <= n; i++)
	 				for(int j = 1;j <= n; j++)
					{
					 		distMatrix[i][j] = 0;
			 		}
	 				for(int i = 0;i < m;i++)
	 				{
					 		scanf("%d %d %d",&a,&b,&d);
					 		distMatrix[a][b] = d;
					 		distMatrix[b][a] = d;
			 		}
			 		scanf("%d %d",&s,&t);
					dijkstra(dist,path,s);
					printf("%d\n",dist[t]);
					showpath(path,s,t);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值