dijkstra算法

#include <stdio.h>
/*
算法描述
建立一个dis数组,长度是城市的数量n,每一个位置保存相应的city到达city1的最短距离
先找到距离city1最近的城市city x,然后遍历它的相邻城市,如果经过city x到达这些相邻城市,
比直接从city 1到达这些相邻城市路程更短,那么就更新dis数组。
接着访问除了city x之外距离city 1最近的城市重复上面的步骤直到所有城市都被访问过。
最终dis数组就保存了所有城市到city1的最短距离。


输入样例

please input the number of cities
5
please input the No.1 line for the lower triangular portion
50
please input the No.2 line for the lower triangular portion
30 5
please input the No.3 line for the lower triangular portion
100 20 50
please input the No.4 line for the lower triangular portion
10 x x 10
the matrix is
0 0 0 0 0
50 0 0 0 0
30 5 0 0 0
100 20 50 0 0
10 0 0 10 0
the final dis array is
0 35 30 20 10
the minimum time required is 35


*/
int getTime(int** matrix, int i, int j)
{
	if (matrix[i][j] == 0)
	{
		return matrix[j][i];
	}
	return matrix[i][j];
}

int main()
{
	printf("please input the number of cities\n");
	int n;
	if (scanf_s("%d", &n) != 1)
	{
		printf("wrong input\n");
		system("pause");
		return;
	}
	int** matrix = NULL;

	matrix = (int**)calloc(n,sizeof(int*));

	for (int i = 0; i < n; i++)
	{
		matrix[i] = (int*)calloc(n,sizeof(int));
	}
	
	for (int i = 1; i < n; i++)
	{
		rewind(stdin);
		char input[100];
		int j = 0;
		printf("please input the No.%d line for the lower triangular portion \n", i);
		gets_s(input, 100);
		//printf("%s\n", input);
			char temp[50];
			int pos = 0;
			int size = strlen(input);
			for (int k = 0; k < size; k++)
			{
				if (input[k] == ' ')
				{
					temp[pos] = '\0';
					int len2 = strlen(temp);
					if (len2 > 0)
					{
						int value = 0;
						if (temp == 'x' || temp == 'X')
							value = 0;
						else
					        value = atoi(temp);

						matrix[i][j] = value;
						j++;
						if (j >= i)
						{
							break;;
						}
						//printf("%d\n",value);
					}
					pos = 0;
				}
				else
				{
					temp[pos] = input[k];
					pos++;
				}

				if (k == size - 1)
				{
					temp[pos] = '\0';
					int len2 = strlen(temp);
					if (len2 > 0)
					{
						int value = 0;
						if (temp == 'x' || temp == 'X')
							value = 0;
						else
							value = atoi(temp);

						matrix[i][j] = value;
						j++;
						if (j >= i)
						{
							break;
						}
						//printf("%d\n", value);
					}
				}

			}

	}
	printf("the matrix is \n");
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			printf("%d ", matrix[i][j]);
		}
		printf("\n");
	}

	int * dis = (int*)calloc(n, sizeof(int));  // 创建一个一维数组,用来保存每个城市到city 1的距离 dis[1] 表示 city 2 到city 1的距离 

	for (int i = 0; i < n; i++)
	{
		dis[i] = getTime(matrix, 0, i);    //根据邻接矩阵 初始化dis数组
	}
	
	int time = dis[1];                    //当前距离city 1最近距离
	int closePos = 1;                     //当前访问的 最近距离城市
	int* visited = (int*)calloc(n,sizeof(int)); //保存已经访问过的城市
	visited[0] = 1;                       //city1 默认已经访问
	for (int i = 0; i < n; i++)                 //找到目前距离city1 最近的城市,初始化 time 和 closePos 
	{
		if (dis[i] < time  && dis[i] >0)
		{
			time = dis[i];
			closePos = i;
		}
	}
	
	int isfinish = 0;                     //表示是否已经访问完所有城市
	while (isfinish == 0)                 //每次访问当前还没访问过的 距离CITY 1最近的城市
	{
		for (int i = 1; i < n; i++)
		{
			if(i == closePos)              //跳过自己
				continue;;
			int littleDis = getTime(matrix, closePos, i);   //找到和当前访问城市相邻的城市
			if (littleDis > 0)
			{                                                               //如果经过当前访问城市到达他的邻居城市 比 从CITY1直接到这个邻居城市距离短,更新dis数组
				if (littleDis + dis[closePos] < dis[i]    || dis[i] == 0)  // 新路径比原路径小或者=0的时候,表示原来没有路径,也要更新
				{
					dis[i] = littleDis + dis[closePos];
				}
			}
		}

		visited[closePos] = 1;  //标记这个城市已经被访问

		for (int i = 0; i < n; i++)                         
		{
			if (visited[i] == 0 && dis[i] > dis[closePos])
			{
				time = dis[i];
				break;
			}
		}
		for (int i = 0; i < n; i++)                      //更新time 和 closePos 找到下一个没访问过的 距离city 1最近的城市
		{
			int temp = dis[i];
			if (visited[i] == 0 && dis[i] <= time)
			{
				time = dis[i];
				closePos = i;
			}
		}
		
		isfinish = 1;
		for (int i = 0; i < n; i++)              //判断是否已经全部访问所有城市
		{
			
			if (visited[i] == 0)
			{
				isfinish = 0;
			}
		}

}

	printf("the final dis array is \n");
	for (int i = 0; i < n; i++)
	{
		printf("%d ", dis[i]);
	}
	printf("\n"); 

	int totaltime = dis[1];
	for (int i = 1; i < n; i++)
	{
		if (dis[i] > totaltime)
		{
			totaltime = dis[i];           //找到到达所有城市中,最远的那个输出 
		}
	}
	printf("the minimum time required is %d ", totaltime);
	
	for (int j = 0; j < n; j++)
	{
		free(matrix[j]);
	}

	free(matrix);
	free(dis);
	free(visited);
	system("pause");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值