天天看点

Dijkstra--简易版 (最短路径)

Dijkstra算法思路:

G={V,E}

1. 初始时令 S={V0},T=V-S={其余顶点},T中顶点对应的距离值

若存在<V0,Vi>,d(V0,Vi)为<V0,Vi>弧上的权值

若不存在<V0,Vi>,d(V0,Vi)为∞

2. 从T中选取一个与S中顶点有关联边且权值最小的顶点W,加入到S中

3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值缩短,则修改此距离值

重复上述步骤2、3,直到S中包含所有顶点,即W=Vi为止

#include<stdio.h>
#include<memory.h>
#define MAX 1000000

int graph[100][100];   //存放邻接矩阵   0表示两点之间没有边 

int vertex[100];  //该点的最短路径是否找到

int dis[100];    //存放begin点到i的最短距离

void Creat_G(int vertnum){
	memset(graph,0,sizeof(graph));
	
	printf("输入图的邻接矩阵:\n");
	
	int i,j;
	for(i=1;i<=vertnum;i++){
		for(j=1;j<=vertnum;j++){
			scanf("%d",&graph[i][j]);
		}
	}
	
	printf("创建完成\n----------------------\n");
} 

void Dijkstra(int begin,int vertnum){
	
	memset(vertex,0,sizeof(vertex));
	vertex[begin]=1;	
	int i,j;
	for(i=1;i<=vertnum;i++){
		if(i==begin) dis[i]=0;
		else dis[i]= MAX;
	}
	for(j=1;j<=vertnum;j++){
		int min=MAX;	//用于记录当前最小的那个点 
		int key=begin;
		for(i=1;i<=vertnum;i++){
			if(!vertex[i]){
				if(graph[begin][i] && graph[begin][i]+dis[begin]<dis[i]){
					dis[i] = graph[begin][i]+dis[begin];
				}
				if(dis[i]<min){
					min=dis[i];
					key=i;
				}	
			}
		}
		vertex[key]=1;    //将当前找到的那个最小值标记为已找到
		begin=key;        //更新begin的值
	}
}

int main(){
	int num;
	printf("输入点的个数:\n");
	scanf("%d",&num);
	printf("-------------------------\n");
	Creat_G(num);
	int begin=3;
	for(begin=1;begin<=num;begin++){
		Dijkstra(begin,num);
		int i;
		for(i=1;i<=num;i++)
			printf("<%d,%d> = %d\t",begin,i,dis[i]);
			printf("\n");
	}
	return 0;
}
           

继续阅读