Dijkstra

#include<stdio.h>
#include<string.h>

#define SIZE 110  
#define INF 1000000;  

int map[SIZE][SIZE];  //邻接矩阵存储 
int len[SIZE];  	//d[i]表示源点到i这个点的距离 
int visit[SIZE];  //节点是否被访问 
int road[SIZE];		//存储路径轨迹下标
int roadInfo[SIZE];  //存储路径轨迹下标对应信息
int n, m;

int dijkstra(int from, int to) {	//从源点到目标点 
	int i,temp;
	memset(road, -1, sizeof(road));
	int road_location = 0;
	memset(roadInfo, -1, sizeof(roadInfo));
	for (i = 1; i <= n; i++) {	//初始化 
		visit[i] = 0;	//一开始每个点都没被访问 
		len[i] = map[from][i];	//先假设源点到其他点的距离 
	}
	int j;
	for (i = 1; i < n; ++i) {	//对除源点的每一个点进行最短计算 
		int min = INF;  //记录最小len[i] 
		int pos = -1;  //记录小len[i] 的点 
		for (j = 1; j <= n; ++j) {
			if (!visit[j] && len[j] < min) {
				pos = j;
				min = len[j];
			}
		}
		if (pos == -1) {	//即没有找到最小值点,所有剩余点都是不可达的(INF)
			return len[to];
		}
		visit[pos] = 1;
		for (j = 1; j <= n; ++j) {
			if (j == from) {
				continue;
			}
			//如果j节点没有被访问过&&j节点到源节点的最短路径>pos节点到源节点的最短路径+pos节点到j节点的路径  
			if (!visit[j] && ((len[pos] + map[pos][j]) < len[j])) {
				//更新j节点到源节点的最短路径	
				len[j] = len[pos] + map[pos][j];
				for (temp = 0; temp < road_location; temp++) {
					if (road[temp] == j) {
						break;
					}
				}
				if (temp == road_location) {	//原数组中没有,则添加下标
					road[road_location] = j;
					road_location++;
				}
				roadInfo[j] = pos;
			}
		}
	}
	return len[to];
}

int main() {
	int i, j;
	//  scanf("%d%d",&n,&m);	//输入数据
	n = 5;	//测试数据 
	m = 7;

	for (i = 1; i <= n; ++i) {	//设一开始每个点都不可达 
		for (j = 1; j <= n; ++j) {
			map[i][j] = INF;
		}
	}
	int a, b, c;	//输入数据
	for (i = 1; i <= m; ++i) {
		scanf("%d%d%d", &a, &b, &c);
		//map[a][b] = map[b][a] = c;
		map[a][b] = c;
	}
	int temp = INF;
	for (i = 1; i <= n; ++i) {
		for (j = 1; j <= n; ++j) {
			if (map[i][j] == temp)
				map[i][j] = map[j][i];
		}
	}
	int ans = dijkstra(2, 5);
	printf("%d\n", ans);
	i = 0;
	while (road[i] != -1) {
		printf("->%d", roadInfo[road[i]]);
		i++;
	}

	return 0;
}

/*
测试数据:
5 7
1 2 2
1 3 4
1 4 3
2 3 1
2 5 4
3 5 2
4 5 2
*/

测试结果:

 测试分析:

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值