#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;
}