Data_Structure/作業/unit12/all-pairs-shortest-path-v2.c
2025-01-20 21:25:33 +08:00

131 lines
2.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Program: all-pairs-shortest-path-v2.c (Report comments/bugs to chikh@yuntech.edu.tw)
Function: 修改all-pairs-shortest-path-v1.c使得A與Y矩陣能依圖內的頂點總數作配置避免
預先配置過大的100x100陣列空間而形成浪費
*/
#include <stdio.h>
#include <stdlib.h> /* for exit() */
#define Inf 1073741823 /* 此為2^30-1的大數字為本程式假設的無限大值可改用limits.h定義的INT_MAX */
void init(int ***A, int ***Y) /* 讀取輸入資料檔、設定相鄰矩陣,把相關資料結構作初始化 */
{
FILE *fptr;
int i, j;
int weight, N;
if ((fptr=fopen("shortestPath.dat","r")) == NULL) { /* 開啟資料檔 */
perror("shortestPath.dat");
exit(1);
}
fscanf(fptr,"%d",&N); /* 讀取圖形節點數 */
*A = (int **)malloc((N+1)*sizeof(int *));
*Y = (int **)malloc((N+1)*sizeof(int *));
for (i = 0; i <= N; i++) {
(*A)[i] = (int *)malloc((N+1)*sizeof(int));
(*Y)[i] = (int *)malloc((N+1)*sizeof(int));
}
(*A)[0][0] = N;
for (i = 1; i <= N; i++ )
for (j = 1; j <= N; j++) {
(*A)[i][j] = (i==j)? 0: Inf; /* 初始化A[1..N][1..N]相鄰矩陣,所有元素均先預設為∞ */
(*Y)[i][j] = (i==j)? i: -1;
}
while (fscanf(fptr,"%d %d %d",&i,&j,&weight) != EOF) {
(*A)[i][j] = weight; /* 讀取連接頂點i與j的邊的權重值 */
(*Y)[i][j] = i;
}
fclose(fptr);
}
void floydWarshall(int ***A, int ***Y)
{
int i, j, k;
int N = (*A)[0][0]; //無法使用sizeof(A[0])/sizeof(A[0][0])判讀維度因以malloc()配置所得記憶體空間不具結構
for (k = 1; k <= N; k++)
for (i = 1; i <= N; i++)
for (j = 1; j <= N; j++)
if ((*A)[i][k] + (*A)[k][j] < (*A)[i][j]) {
(*A)[i][j] = (*A)[i][k] + (*A)[k][j];
(*Y)[i][j] = (*Y)[k][j];
}
//上面二層for迴圈用於檢視/修正每二頂點(i,j)之間有否經由k(中繼頂點)能得更小距離值
}
void printMatrix(int **A)
{
int i, j;
int N = A[0][0];
for (i = 1; i <= N; i++) {
for (j = 1; j <= N; j++) {
if (A[i][j] == Inf)
printf("%5s","");
else
printf("%4d",A[i][j]);
}
printf("\n");
}
}
void backtrack(int **Y, int source, int dest)
{
int k = Y[source][dest];
if (source == dest) {
printf("頂點%d →",source);
return;
}
if (Y[source][dest] == -1) {
printf("頂點%d與%d之間沒有路徑存在 ",source,dest);
return;
}
backtrack(Y,source,k);
printf(" %d →",dest);
}
void traverseMatrix(int **Y)
{
int i, j, k, source, sink;
printf("\n源點 => ");
scanf("%d",&source);
printf("終點 => ");
scanf("%d",&sink);
printf("最短路徑:");
backtrack(Y,source,sink);
printf("\b\b ");
}
void freeMemory(int **A, int **Y)
{
int i, N = A[0][0];
for (i = 0; i <= N; i++) {
free(A[i]);
free(Y[i]);
}
free(A);
free(Y);
}
int main() {
int **A, **Y;
init(&A,&Y); /* 讀取輸入資料檔、設定相鄰矩陣,並把相關資料結構作初始化 */
floydWarshall(&A,&Y);
printMatrix(A);
traverseMatrix(Y);
freeMemory(A,Y);
return 0;
}